【问题标题】:Program freezes when freeing memory释放内存时程序冻结
【发布时间】:2013-09-23 01:33:34
【问题描述】:

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

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

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*));

【问题讨论】:

  • 这是从多个线程调用的吗?
  • 您的代码看起来不错。这将有助于了解您如何 malloc img 和 img->imgdata。也许你不止一次地释放它?
  • 我认为我不会多次释放它。我想我意识到了一个问题。 imgdata 并不总是分配给它的内存。释放尚未分配的内存会导致这种类型的冻结吗?如果是,如何检查内存是否已分配给 imgdata?
  • 是的,这会导致未定义的行为。跟踪内存是否已分配给指针的一种方法是在第一次机会时将指针设置为 NULL,保持这种状态,直到您为其分配内存,然后在释放该内存时将其设置回 NULL。

标签: c


【解决方案1】:

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

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

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

这里有一个提示。最好的风格是始终像这样编写你的 malloc:

Image *img = malloc(sizeof *img);

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 2023-03-15
    • 2018-09-01
    相关资源
    最近更新 更多