C 使用灵活的数组成员释放动态分配的结构

C 使用灵活的数组成员释放动态分配的结构,c,malloc,dynamic-allocation,C,Malloc,Dynamic Allocation,我的数据结构定义如下: 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

我的数据结构定义如下:

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,这会导致内存泄漏。我为此目的构建数据的方式或分配内存的方式是否存在根本性的问题

==注意==


我通过使用指针而不是显式声明的数组解决了这个问题。然而,我仍然对为什么这不起作用的简明答案感兴趣。

这看起来大错特错。我认为应该是这样的:

// step 1: Allocate n items:

struct varr * p = malloc(sizeof *p + n * sizeof(double));
if (p) { p->n = n; }


完成后,不要忘记说
free(p)

我昨晚遇到了同样的问题。在谷歌搜索了几个小时后,我在一篇教程中找到了这个非常简单但聪明的答案:

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);
    }
}
void free_结构(结构*ts)
{
//释放所有符合我们结构的内存
如果(ts){
for(int i=0;i计数;i++)
自由(ts->str[i]);
免费(ts);
}
}

您可能知道,每次调用
malloc
都会让操作系统给您一些内存,并记住它的大小和属性。因此,如果调用
free
,则可以清除数组或指针

示例:

char* array = malloc(16 * sizeof(char));
char* single = malloc(sizeof(char));

free(array);
free(single);
正如您所看到的,一次
malloc
,您总是可以得到一个
免费
。这是因为操作系统知道您分配了多少字节,它不关心它是什么类型以及创建了多少实例。(注:这就是为什么在C++中代码< >删除>代码>和<代码>删除[]/Cord>,因为应用程序需要知道要运行什么析构函数,清理的控制不被只留给OS……< /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;
}
您仍然可以在一个
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));
//每个*s*的int指针实际上是一个由25个int组成的衰减数组
对于(int i=0;iSize;++i)
s->ArrayOfPointers[i]=malloc(25*sizeof(int));
释放时:

for (int i = 0; i < s->Size; ++i)
    free(s->ArrayOfPointers[i]);

free(s);
for(int i=0;iSize;++i)
免费(s->ArrayOfPointers[i]);
免费的;

但关键是,带有FAM的结构仍然在一次
free
调用中被释放。循环正在释放分配的指针数据,这相当于释放动态分配的2D数组。

@KerrekSB抱歉,这是一个输入错误。我实际上没有使用sizeof(sizeof())。我会编辑。
struct poly
struct varr
之间的关系是什么?
varr::n
应该是
size\u t
@KeithRandall:也是一个打字错误。KerrekSB-true-但这是C,而不是C++@PWhite:如果泄漏内存,您一定是在做其他错误的事情(如Kerreb-SB指出的,如果
realloc
失败,则关闭
p
)。您不需要做任何特殊的事情来释放包含灵活数组成员的内存
malloc
/
free
与您使用内存的目的完全无关。这会导致我的程序中断-请稍等,我将向您提供更多信息。很抱歉,“一分钟”变成了一个小时-奇怪的错误似乎与此代码无关。无论如何,这并没有解决问题。我比以前有更多的内存泄漏。我现在接受你的答案,即使它不能解决问题,因为它指出了一些原始代码出错的地方。这篇文章已经有将近三年的历史了。但是我遇到了这个问题,没有找到任何解决方案/解释。我认为最初的问题归结为我三年前是一个相当差劲的C程序员。但这是最清楚地解释了问题和解决方案的答案,本着作为社区wiki改进堆栈溢出的精神,我已经将公认的答案转换为这一点。
// 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);