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

如何释放malloc()分配的结构数组?,c,arrays,memory-management,malloc,free,C,Arrays,Memory Management,Malloc,Free,我一直在从事一个使用结构作为字符串存储的项目。我声明结构由char类型的成员组成: struct datastore1 { char name[50]; char address[50]; char email[50]; char number[50]; char idnum[50]; }; 我知道我可以只做char*name,char*address…,但假设我们指定它的最大长度为50。然后在我使用结构的函数上,我用索引大小30对其进行malloc:

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

struct datastore1
{
    char name[50];
    char address[50];
    char email[50];
    char number[50];
    char idnum[50];
};
我知道我可以只做
char*name,char*address…
,但假设我们指定它的最大长度为50。然后在我使用结构的函数上,我用索引大小30对其进行malloc:

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

假设我通过访问每个索引完成了将所有字符串复制到结构中,那么我应该如何释放调用malloc后使用的分配内存?我在节目结束时尝试了免费(dsdata),但我不确定这是否正确。我应该单独释放每个索引吗?请开导我。提前感谢您的反馈

据我所知,您仅使用
malloc
datastore1
struct数组分配空间,因此只需执行
free(dsdata)

如果在结构中有指针,并且使用
malloc
分配每个指针,那么只需要
free
首先释放每个指针即可。

1。 如何释放调用malloc后使用的已分配内存

我在节目结束时尝试了免费(dsdata),但我不确定这是否正确

free(dsdata)
很好,因为您只需一次调用
malloc
就可以分配整个空间,方法是:

struct datastore1 *dsdata = malloc(30 * sizeof(struct datastore1));
引用标准(C18)7.22.3.4“malloc功能”(强调我的功能):

7.22.3.4 malloc功能

概要

一,

#包括
void*malloc(大小);
描述

2 malloc函数为大小由size指定且值不确定的对象分配空间

返回

3 malloc函数返回空指针或指向分配空间的指针

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

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


2. 我应该单独释放每个索引吗

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

引用现行标准(C18),7.22.3.5/3-“自由功能”(强调我的):

否则,如果参数与内存管理函数先前返回的指针不匹配,或者如果空间已通过调用free或realloc取消分配,则行为未定义


以上两个答案都是正确的,但为了充分了解它是如何工作的,我建议您学习如何使用
valgrind

要检查程序释放的内存是否正确使用

valgrind -v --leak-check=full --track-origins=yes ./your-program
这将在valgrind的虚拟处理器上执行您的程序,并提供有关所用资源的完整反馈

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

如何释放调用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

我应该单独释放每个索引吗

不,因为内存块只分配一次,而且您只需要释放一次

让我进一步扩展一下

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]);
struct datastore1*obj3[3];

for(int i=0;i
free(dsdata)
是正确的。它实际上相对简单-每个malloc应该有一个与malloc返回的地址完全相同的free。我建议
struct datastore1*dsdata=malloc(30*sizeof(*dsdata))
…如果需要释放内部指针,那么这与单独释放每个数组元素仍然是不同的,因为OP认为可能需要这样做。
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]);