C中“免费”的奇怪行为

时间:2013-04-23 08:45:04

标签: c memory-management free calloc

我正在编写一个代码来检查我编写的两个函数是否分配和释放内存。这两个功能基本上是

int createBaseName(char ***imageName, char **groupName, char *name)
{
    *imageName = calloc(BASELINEC, sizeof(char *)); //This is a 2D array (array of str)
    *groupName = calloc(MINILINE, sizeof(char)); // This is a 1D array (just an str)

    sprintf(*groupName, "%s_BGr.fbi", name);
    for(bb = 0; bb < BASELINEC; bb++) {
       (*imageName)[bb]  = (char *)calloc(MINILINE, sizeof(char));
        if (bb < 9)
           sprintf((*imageName)[bb], "%s_BIm_00%d.fbi", name, bb+1);
        else if (bb < 99) 
           sprintf((*imageName)[bb], "%s_BIm_0%d.fbi", name, bb+1);
        else
           sprintf((*imageName)[bb], "%s_BIm_%d.fbi", name, bb+1);
   }
   return 0;
}

int freeBaseName(char **imageName, char *groupName)
{
   int  bb;

   for(bb = 0; bb < BASELINEC; bb++)
      free(imageName[bb]);

   free(imageName);
   free(groupName);

   return 0;
}

在我编写的用于检查这两个功能的程序中,我不小心一个接一个地调用了createBaseNamefreeBaseName,而然后我试图打印出来{{ 1}}和imageName。这导致groupName打印得很好,并且在groupName打印之前,有400个名称中的大约120个被罚款。

问题:为什么内存的imageName没有工作?还是需要时间来释放记忆?

4 个答案:

答案 0 :(得分:2)

free()函数仅将内存块标记为“空闲”。这意味着,在任何时刻,它都可以被其他功能使用。它不会清理内存,因为它应该由下次获取此内存块的程序处理。

您实际执行的操作是未定义的行为

答案 1 :(得分:2)

当你free记忆时,你就失去了对它的控制。您释放内存以供任何其他用途。它不会立即被其他函数或变量覆盖或占用。但它可以在任何未知时间被其他函数或变量使用。在此之前,您将能够访问内存。但由于无法确定其他人使用它的时间,行为 未定义

  • 如果您想确保使用相同的变量无法访问内存,请在NULL之后将其设置为 free

答案 2 :(得分:1)

free标记内存可以重用。在free之后,您有责任不再尝试使用内存。释放后内存可能仍然完好无损,因此groupName打印正常。但是它也可以重新分配,因此imageName

中的段错误

答案 3 :(得分:1)

释放内存时,指针仍指向已分配的内存,其内容可能(或可能不会)被其他数据覆盖。这就是为什么它似乎有时会起作用的原因。 未定义的行为往往是未定义的。