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

3

我一直在开发一个使用结构体作为字符串存储的项目。我声明了一个包含char类型成员的结构体:

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

我知道可以这样写:char *name, char *address...,但是如果我们指定它们的最大长度为50,那么在使用该结构的函数中,我将使用大小为30的索引对其进行内存分配:
struct datastore1 *dsdata = malloc(30 * sizeof(struct datastore1));

据说我已经通过访问每个索引将所有字符串复制到结构体中,那么在调用malloc后使用的分配内存应该如何释放呢?我尝试在程序结尾处执行free(dsdata),但我不确定这是否是正确的方法。我应该逐个释放每个索引吗?请指教。非常感谢您提供的反馈!


4
free(dsdata)是正确的。实际上很简单 - 每个malloc应该有确切的一个free,使用相同地址,这个地址是由malloc返回的。 - kaylum
我建议使用 struct datastore1 *dsdata = malloc(30 * sizeof(*dsdata)); - 0___________
4个回答

6

我应该如何释放调用malloc后使用的已分配内存?

考虑以下示例:

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

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

enter image description here

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

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

enter image description here

我需要逐个释放索引吗?

不需要,因为内存块只分配一次,你只需要调用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是指针数组,每个索引都指向不同的内存部分,因此需要逐个释放。

enter image description here


注意:为了简单起见,我没有考虑从malloc返回的返回值。必须对malloc返回的返回值进行空指针检查。


1

1.

我在调用malloc后,应该如何释放已分配的内存?

我试过在程序末尾使用free(dsdata),但不确定是否正确。

free(dsdata)是可以的,因为你通过一次调用malloc来分配整个空间:

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一次性分配了所有所需空间,并返回指向该数组第一个结构变量的指针,该指针分配给dsdata的指针。

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


2.

我应该逐个释放每个索引吗?

不需要,更重要的是,你不应该这样做;这将会导致未定义的行为

引用当前标准(C18),7.22.3.5/3 - "free函数"(强调是我的):

否则,如果参数不匹配先前由内存管理函数返回的指针,或者如果空间已被调用free或realloc释放,则行为是未定义的。


0
据我所知,您只使用了malloc来为datastore1结构体数组分配空间,因此只需执行free(dsdata)即可。
如果在结构体中您有指针,并且您使用malloc为每个指针分配内存,那么您需要先free每个指针。

1
如果需要释放内部指针,那么这仍然不同于单独释放每个数组元素,正如OP所认为可能是必要的。 - John Bollinger

0
上面的两个答案都是正确的,但要完全理解它是如何工作的,我建议您学习如何使用 valgrind。 要检查程序是否正确释放了内存,请使用
valgrind -v --leak-check=full --track-origins=yes ./your-program

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接