如何释放由 malloc() 分配的结构数组?

How to free() an array of structs allocated by malloc()?

我一直在从事一个使用结构作为字符串存储的项目。我声明了一个由 char 类型成员组成的结构:

struct datastore1
{
    char name[50];
    char address[50];
    char email[50];
    char number[50];
    char idnum[50];
};

我知道我可以做 char *name, char *address... 但假设我们指定它的最大长度为 50。然后在我使用该结构的函数上,我 malloc 了它的索引大小为 30 :

struct datastore1 *dsdata = malloc(30 * sizeof(struct datastore1));

据说我通过访问每个索引完成了将所有字符串复制到结构中,我应该如何释放调用 malloc 后使用的已分配内存?我尝试在程序结束时执行 free(dsdata) 但我不确定这是否正确。我应该单独释放每个索引吗?请赐教。预先感谢您的反馈!

据我了解,您仅使用 mallocdatastore1 结构数组分配 space,因此只需执行 free(dsdata) 即可。

如果在结构中你会有指针,你会使用 malloc 来分配它们中的每一个,而不是你需要首先 free 它们中的每一个。

1.

How should I free the allocated memory that was used after calling malloc?

I tried doing free(dsdata) on the end of the program but I am not sure if it's the right way.

free(dsdata) 很好,因为 你只通过一次调用 malloc 就分配了整个 space:

struct datastore1 *dsdata = malloc(30 * sizeof(struct datastore1));

引用标准 (C18),7.22.3.4 - “malloc 函数”(强调我的):

7.22.3.4 The malloc function

Synopsis

1

 #include <stdlib.h>
 void* malloc(size_t size);

Description

2 The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.

Returns

3 The malloc function returns either a null pointer or a pointer to the allocated space.

使用free(dsdata)是正确的,因为malloc一次分配了所有需要的space,并返回一个指向该数组的第一个结构变量的指针,该变量分配给dsdata.

的指针

free() 函数“知道”dsdata 是对整个分配的 space 的引用。您不需要单独释放内存中类型为 struct datastore1 的 30 个结构中的每一个。


2.

Should I free each indexes individually?

不,你不需要,更重要的是你不应该这样做;这将是 Undefined Behavior:

引用自当前标准 (C18),7.22.3.5/3 - “自由函数”(强调我的):

Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

上面的两个答案都是正确的,但要完全理解它是如何工作的,我建议您学习如何使用 valgrind
检查程序是否正确释放内存使用

valgrind -v --leak-check=full --track-origins=yes ./your-program

这将在 valgrind 的虚拟处理器上执行您的程序,并为您提供有关已用资源的完整反馈。

基本上 C 编程语言中数组定义上下文中的运算符 [] 会导致创建(可以说是为了简化)static 数组 - 这意味着数组包含在大小中结构的(如果定义为结构的一部分)或存储在堆栈中(如果在函数中或全局定义)。
malloc函数returns你可以使用的数据块地址。这个块的大小至少和你要求的一样大。当你使用 free 你释放这个块,在这种情况下意味着这个地址指向的块中的所有数据都将被释放。

How should i free the allocated memory that was used after calling malloc?

考虑下面的例子,

struct datastore1 *obj1 = malloc(sizeof(struct datastore1));
free(obj1);

这里 obj1 指向与 datastore1 大小相同的内存块为了释放你需要发送由 malloc 分配的地址。

同样,

struct datastore1 *obj2 = malloc(3 * sizeof(struct datastore1));
free(obj2);

obj2 指向一块大小为 3 * sizeof(datastore1) 的连续内存,您需要将基地址传递给 free

Should i free each indexes individually?

不,因为内存块只分配一次,你只需要 free 一次。

让我进一步扩展,

struct datastore1 *obj3[3];
for(int i=0;i<3;i++)
   obj3[i] = malloc(sizeof(struct datastore1));

for(int i=0;i<3;i++)
    free(obj3[i]);

这里obj3是指针数组,每个索引指向内存的不同部分,因此需要单独释放。


注意:为简单起见,我没有考虑 malloc 的 return 值。必须对 malloc return 值进行空检查。