当您尝试释放()在c中已经释放的内存时会发生什么?

当您尝试释放()在c中已经释放的内存时会发生什么?,c,memory,memory-management,C,Memory,Memory Management,例如: char * myString = malloc(sizeof(char)*STRING_BUFFER_SIZE); free(myString); free(myString); 这样做有没有副作用 是的,您可以获得导致程序崩溃的双重自由错误。它与malloc的内部数据结构有关,以跟踪分配的内存。根据您在哪个系统上运行它,不会发生任何事情,程序会崩溃,内存会损坏,或任何其他有趣的效果。不要这样做。如果释放的内存在调用free之间被重新分配给其他内存,那么事情就会变得一团糟。一无所有、

例如:

char * myString = malloc(sizeof(char)*STRING_BUFFER_SIZE);
free(myString);
free(myString);

这样做有没有副作用

是的,您可以获得导致程序崩溃的双重自由错误。它与malloc的内部数据结构有关,以跟踪分配的内存。

根据您在哪个系统上运行它,不会发生任何事情,程序会崩溃,内存会损坏,或任何其他有趣的效果。

不要这样做。如果释放的内存在调用
free
之间被重新分配给其他内存,那么事情就会变得一团糟。

一无所有、静默内存损坏或分段错误。

不是那么聪明。谷歌的双重免费漏洞。释放后将指针设置为空以避免此类错误。

释放后始终将指针设置为空。 尝试释放空指针是安全的

您可以编写自己的免费包装来自动完成这项工作。

坏东西(TM)


真的,我认为它是未定义的,所以任何事情,包括与NORAD的主机玩“全球热核战争”,都可能会导致程序崩溃、内存损坏或产生其他更微妙的负面影响。删除内存后,最好将其设置为NULL(0)。尝试释放空指针没有任何作用,并且保证是安全的。对于C++中的删除也是如此。

< P>答案摘要:

是的,坏事可以而且可能会发生

要防止这种情况,请执行以下操作:

free(myString);
myString = NULL;
请注意,如果创建了其他引用,则对内存的所有引用必须设置为
NULL

另外,使用
NULL
调用
free()
不会导致任何操作。有关更多信息,请参见:

简而言之:“未定义的行为”


(现在,这其中包括了什么,以及为什么其他人已经说过了。我只是觉得这个词在这里值得一提,因为它很常见)。

这是一章一节

如果[到
free
函数的]参数与
calloc
先前返回的指针不匹配,
malloc
realloc
函数,或者如果通过调用
free
realloc
释放空间, 该行为未定义。(,第7.20.3.2节)


下面这个公认奇怪的宏是一个有用的替代品,它可以清除几类安全漏洞,并帮助调试,因为对free()d区域的访问更容易出错,而不是悄悄地破坏内存

#define my_free(x) do { free(x); x = NULL; } while (0)

do-while循环是为了帮助周围的代码更容易地消化多个语句。e、 g.如果(完成)我的自由(x)

另一个有趣的情况:

char * myString = malloc(sizeof(char)*STRING_BUFFER_SIZE);
char * yourString = myString;

if (myString)
{
    free(myString);
    myString = NULL;
}
// Now this one is safe, because we keep to the rule for 
// setting pointers to NULL after deletion ...
if (myString)
{
    free(myString);
    myString = NULL;
}

// But what about this one:
if (yourString)
{
    free(yourString);
    yourString = NULL;
}

//?!? :)

它(可能)会产生错误。

不幸的是,您无法编写一个为您执行此操作的免费包装器,指针是通过值而不是引用传递的。i、 e.Free(void**p){Free(*p);*p=NULL;}使用.ajbl重新工具代码并不容易,请使用宏#定义freep(x)(free(x);x=0;)是个坏主意,因为它不适用于常量值。你尽可能使用常量值,不是吗?@Steve:我知道这很古老,但我们不是在别处讨论过将常量限定指针传递到
free
是无效的(无论从概念上还是形式上,除非你放弃限定符)?:-)@R..:我说的是char*constptr=malloc(STRING\u BUFFER\u SIZE);免费(ptr)。我不认为这在形式上或概念上是无效的。之后,
ptr=0不在卡片上。因此,如果你像德里克说的那样定义了一个宏
freep
,那么你就不能在
ptr
上使用它。请注意,如果你制作了指针的任何副本,那么这些副本也应该设置为NULL。似乎社区更倾向于将答案摘要放在实际问题中,而不是作为一个仍然被隐藏的问题…坏主意,因为它不适用于常量值。在可能的情况下使用const值,不是吗?“#定义我的_free(x){free(x);x=NULL;}”不会也起作用吗?不,扩展后if(done){free(x);x=NULL}中有一个非法分号;还有别的吗;祝您在原始源代码中找到“else without matching if”错误。C使用逗号运算符是有原因的<代码> >定义MyAyFree(x)(自由((x)),(x)=0)< /Cord>,即使内存没有重新分配,两个调用之间也会发生混乱。您的Free()包装必须是宏,或者必须使用标准Free()函数的不同接口。谷歌为“鼻妖”找出My.FY:当C或C++称“未定义”时它们通常意味着“崩溃”或“内存损坏”或其他同样可怕的事情。当心。不,它们的真正含义是“未定义”。这只是碰巧包括崩溃和内存损坏。@OrionEdwards例如,编译器可能决定启动NetHack。当您访问超出范围的内存时,会发生Segfaults。