c - 从动态分配的结构数组中释放特定元素

标签 c struct dynamic-memory-allocation dynamic-arrays

我有一个简单的结构体s_personconstructor(int number),它接受我们想要构造的s_person的数量并返回一个指针到它。

在这个例子中,我构造了 2 个 s_person,并为其属性 name 赋值。并且它有效。

#include<stdio.h>
#include<stdlib.h>
#define MAX_NAME 50
typedef struct s_person {
    char *name;
    double grade;
}s_person;

s_person* construct(int number){
    int each;
    s_person *person = (s_person*)malloc(sizeof(s_person) * number);
    if(person){
        for(each=0; each<number; each++){
            person[each].name = (char*)malloc(sizeof(char));
        }
    }
    return person;
}

main()
{
    s_person *person = construct(2);
    person[0].name = "steven";
    person[1].name = "michael";

    printf("%s %s\n", person[0].name, person[1].name);

    // This works
    free(&person[0]);
    printf("%s %s\n", person[0].name, person[1].name);

    //This doesn't work
    free(&person[1]); // Crashes here
    printf("%s %s\n", person[0].name, person[1].name);
}

当我尝试释放元素 0 并再次打印值时,它起作用了。

但是如果我尝试释放元素 1 并打印值,它就会崩溃。

那么,如何为该结构数组中的特定元素释放内存?

这是使用constructor(int number)函数为结构数组动态分配内存的有效方法还是有更好的做法?

最佳答案

您的程序有几个错误,其中大部分与内存分配和内存泄漏有关。

例如,在函数construct中,您为数据成员name分配内存

    for(each=0; each<number; each++){
        person[each].name = (char*)malloc(sizeof(char));

然后在 main 中覆盖这个值

person[0].name = "steven";
person[1].name = "michael";

因此您无法再访问已分配的内存,也无法释放它。

至于这个说法

free(&person[1]); 

那么你没有单独分配person[1]。您为该结构的两个实例分配了一个范围。因此您只能释放这个分配的范围。

您可以在函数构造中通过分配指向结构的指针数组来单独分配结构的每个实例。在这种情况下,该函数将如下所示

s_person ** construct( int number )
{
    int each;

    s_person **persons =  ( s_person ** ) malloc( number * sizeof( s_person * ) );

    if ( persons != NULL )
    {
        for ( each = 0; each < number; each++ )
        {
            persons[each] = ( s_person * )malloc( sizeof( s_person ) );
            if ( persons[each] != NULL )
            {
                persons[each]->name = ( char* )malloc( MAX_NAME );
            }
        }
    }

    return persons;
}

并且在 main 中,您必须使用标准 C 函数 strcpy 来使用字符串文字初始化已分配结构的数据成员 name

#include <string.h>

//...

int main( void )
//^^^^^^^^^^^^^^
{
    s_person **persons = construct( 2 );
    if ( persons[0] ) strcpy( persons[0]->name, "steven" );
    if ( persons[1] ) strcpy( persons[1]->name, "michael" );

    //...

在这种情况下,您可以删除每个单独的元素。例如

free( persons[0]->name );
free( persons[0] );
persons[0] = NULL;

free( persons[1]->name );
free( persons[1] );
persons[1] = NULL;

// and at last

free( persons );

关于c - 从动态分配的结构数组中释放特定元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30422565/

相关文章:

c - 如何将(深层)整个结构及其所有成员复制到另一个结构中? (经过编辑以使目标更容易实现)

c - 如何在 C 中分配新的字符串值

json - 解码后的 json 响应返回空结构

c++ - 如何从链表中删除正确的元素?

c++ - 动态分配数组中的一个值总是打印垃圾值

python - 为什么这个 C 方法会出现段错误?

c - 在 64 位环境中将 32 位十六进制读入 long

go - 将 yaml 文件解析为 go 中的预定义结构

c - 结构符号

c - 我做错了什么 - C 指针