我的数据结构定义如下:
struct varr {
int n; //length of data array
double data[];
};
数据数组最初需要大小为1,但允许增加的可能性。
为struct varr *
分配空间时,我使用
struct varr *p = malloc(sizeof(struct varr) + sizeof(double));
当重新分配空间以增加数据数组的大小时,我使用
p = realloc(p, sizeof(struct varr) + p->n * sizeof(double));//p->n having already been set
我的问题是“我应该如何释放为此结构分配的内存?”
我尝试过一个简单的free(p);
,但根据memcheck会导致内存泄漏。对于我为此目的构建数据的方式,或者我如何分配内存,是否存在根本性的错误?
==注==
我通过使用指针而不是显式声明的数组来解决问题。然而,我仍然对一个简明的答案感兴趣,为什么这不起作用。
答案 0 :(得分:5)
首先,@ Waanton的John Findlay例子与此无关。他使用的THESTRUCT
实际上是一个指针数组,因此他首先需要释放所有指针然后释放结构。
返回主题:
您可能知道,每次调用malloc
都会让操作系统给您一些记忆并记住它的大小和属性。因此,如果您调用free
,则可以清除数组或指针。
示例:
char* array = malloc(16 * sizeof(char));
char* single = malloc(sizeof(char));
free(array);
free(single);
正如您所看到的,您总是会为一个free
获得一个malloc
。这是因为操作系统知道你分配了多少字节,它并不关心它是什么类型以及创建了多少个实例。 (注意:这就是为什么C ++中delete
和delete[]
之间存在差异的原因,因为应用程序需要知道要运行哪些析构函数,清理控制不仅仅留给操作系统...)< / p>
从这里开始,我们可以假设如果我们使用单个malloc
将结构分配为一个块,则可以使用单个free
调用释放它。
此示例适用于我而没有任何泄漏:
#include <stdlib.h>
typedef struct Array_t
{
int Length;
double Data[];
} Array;
Array* create_array(int length)
{
Array* array = malloc(sizeof(Array) + length * sizeof(double));
if (array != NULL)
array->Length = length;
return array;
}
void delete_array(Array* array)
{
free(array);
}
int main()
{
Array* array = create_array(100);
if (array == NULL)
return EXIT_FAILURE;
for (int i = 0; i < array->Length; ++i)
{
array->Data[i] = 1.7 * (i + 3);
}
delete_array(array);
return EXIT_SUCCESS;
}
当然,如果你像约翰·芬德利(John Findlay)那样用
来做更复杂的事情struct SomeStruct
{
int Size;
int* ArrayOfPointers[];
}
你仍然可以在一个malloc
中创建这个结构,例如
// *s* contains an array of 14 int pointers (int*)
struct SomeStruct* s = malloc(sizeof(SomeStruct) + 14 * sizeof(int*));
s->Size = 14;
核心问题是int* ArrayOfPointers
是一个指针数组,因此要正确初始化它,你还需要
// each of the *s*'s int pointers is actually a decayed array of 25 ints
for (int i = 0; i < s->Size; ++i)
s->ArrayOfPointers[i] = malloc(25 * sizeof(int));
释放时:
for (int i = 0; i < s->Size; ++i)
free(s->ArrayOfPointers[i]);
free(s);
但关键是在一次free
调用中仍然可以释放具有FAM的结构。循环释放分配的指针数据,这相当于释放动态分配的2D数组。
答案 1 :(得分:3)
看起来很不对劲。我认为它应该是这样的:
// step 1: Allocate n items:
struct varr * p = malloc(sizeof *p + n * sizeof(double));
if (p) { p->n = n; }
// step 2: Reallocate to hold m items:
struct varr * tmp = realloc(p, sizeof *tmp + m * sizeof(double));
if (tmp) { p = tmp; p->n = m; }
完成后,请不要忘记说free(p);
。
答案 2 :(得分:0)
void free_struct( THESTRUCT * ts )
{
// free all memory accoiated with our structure
if(ts){
for(int i = 0; i<ts->count; i++)
free(ts->str[i]);
free(ts);
}
}