简体   繁体   English

C语言中“免费”的奇怪行为

[英]Strange behavior for 'free' in C

I was writing a code to check if two functions I wrote to allocate and deallocate memory worked. 我正在编写代码,以检查我编写的用于分配和取消分配内存的两个函数是否正常工作。 The two functions were essentially 这两个功能本质上是

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;
}

and

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

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

   free(imageName);
   free(groupName);

   return 0;
}

In the program I wrote to check these two functions, I accidentally called createBaseName and freeBaseName one after the other, and then I was attempting to print out imageName and groupName . 在编写用于检查这两个功能的程序中,我不小心一个freeBaseName一个地调用了createBaseNamefreeBaseName然后尝试打印imageNamegroupName This resulted in groupName printing just fine, and about a 120 of 400 names of imageName printing fine before it segfaulted. 这样就可以很好地打印groupName ,在出现段错误之前可以在400个imageName名称中打印120个左右的名字。

QUESTION: Why wasn't the free -ing of the memory working? 问题:为什么内存的free不起作用? Or does it take time to free the memory? 还是释放内存需要时间?

free() function only marks a memory block as "free". free()函数仅将内存块标记为“空闲”。 That means, that at any moment, it cam be used by other function. 这意味着,它随时都可以被其他功能使用。 It does not clean up the memory as it supposed to be handled by the program that will get this memory block next time. 它不会清除内存,因为它应该由下次将获取该内存块的程序处理。

What you actually done, is undefined behavior . 您实际上所做的是未定义的行为

When you free a memory, you just loose control over it. free内存时,您只是对其失去控制。 You release the memory for any other use. 您释放内存以用于任何其他用途。 It does not get overwritten or occupied by other function or variable immediately. 它不会立即被其他函数或变量覆盖或占用。 But it can be used by other function or variable at any unknown time. 但是它可以在任何未知时间被其他函数或变量使用。 Until then, you will be able to access the memory. 在此之前,您将能够访问内存。 But as one cannot be sure about the time when it will be used by others, the behaviour is undefined . 但是由于无法确定其他人将使用它的时间,因此行为不确定的

  • In case you want to make sure that the memory become inaccessible using the same variable, set them to NULL after free ing. 如果要确保使用相同的变量无法访问内存,请在free后将其设置为NULL

free marks the memory as being free for reuse. free将内存标记为空闲以供重用。 After free you are responsible for not attempting to use the memory again. free您有责任不尝试再次使用该内存。 It is possible that the memory is still intact after freeing, hence your groupName printing fine. 释放后,内存可能仍然完好无损,因此您的groupName打印正常。 However it could also have been reallocated, hence the segfault in imageName 但是也可以重新分配它,因此imageName

When freeing memory, the pointers still point to the memory that was allocated, and its contents may (or may not) be overwritten by other data. 释放内存时,指针仍指向已分配的内存,其内容可能(也可能不会)被其他数据覆盖。 This is why it seems to work some times. 这就是为什么它有时会起作用的原因。 Undefined behavior tends to be, well, undefined. 未定义的行为往往是未定义的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM