1

我有一个具有释放结构内存功能的程序。它通常工作正常,但有时它只是冻结。

这是我试图释放内存的结构:

struct Image {
   unsigned int height;
   unsigned int width;
   unsigned int maxvalue;
   unsigned int *imgdata[];
};

这是释放内存的功能(printfs 只是在那里检查它在哪里冻结)

void    Image_Delete (Image *img)
{
    printf("1");
    free(img->imgdata);
    printf("1");
    free(img);
    printf("1");
}

有时这可以正常工作,但程序通常会冻结在free(img);. Image_Delete我的功能有什么错误吗?

这是我的 img 和 img->imgdata 的 malloc 行

Image *img= (Image*)malloc(sizeof(Image*));
img->imgdata[height*width]= (unsigned int*)malloc(height*width*sizeof(unsigned int*));
4

1 回答 1

2

您的第一个 malloc 没有分配足够的空间:

Image *img= (Image*)malloc(sizeof(Image*));

这为“指向图像的指针”分配了足够的空间,但您即将将其用作“图像”,即 3 个整数和一个指针。因此,当您开始修改新分配的“图像”时,您最终会覆盖任意内存。此外,您的free(img->imgdata)调用使用的指针未包含在img的分配空间中,因此可能已被程序的其他部分修改;调用free未返回的值malloc可能会导致 malloc 内部状态的任意损坏,所以一切皆有可能。

这里有一个提示。最好的风格是总是这样写你的 malloc:

Image *img = malloc(sizeof *img);

使用*variable而不是重复类型更不容易出错,尽管您最终仍会重复变量名称,因此它并不完美。并且没有必要强制转换 malloc 返回的 void* 。

另外,要回答您在评论中提出的问题:调用freeon总是安全的NULL,否则您只能在由 . 返回的指针上调用它malloc。所以如果你不马上填img->imgdata,你应该把它清为0。其实用callocinsteadmalloc会更好;对于像这样的小对象Image,开销可以忽略不计。

于 2013-09-23T02:02:43.260 回答