2011-05-16 121 views
4

我的问题很简单。假设我们有:指针运算后释放指针

char* ptr = (char*) malloc(sizeof(char)*SIZE); 
ptr+= SIZE/2; 
free(ptr); 

当我们释放指针时会发生什么?它是未定义的操作? 它是否释放所有的SIZE缓冲区或仅剩余的SIZE/2? 预先感谢您为我消除歧义。

+0

谢谢大家,非常具体的答案,现在我知道如何在我的引擎中处理它。我认为暗恋会发生,直到我真正尝试了它,用gcc和C++,并没有得到任何错误或暗恋。 我认为它弄糟了我的记忆,但迟早会出现,因为如果一个人留下,它会变得很讨厌。 – Lefteris 2011-05-16 06:24:57

+1

请注意,从来没有理由在C中从malloc中输入结果。 – Lundin 2011-05-16 06:37:18

回答

9

你的程序就会崩溃:免费()操作实际上是在C语言很简单,但只适用于原有分配的地址。

典型内存分配器工作原理是这样的伪代码:

  • 问ALLOC 64字节
  • 分配器allocs 70个字节(6字节以上)
  • 前2个字节被设置为一个“签名“,由分配器识别以识别由他分配的存储器的模式
  • 接下来的4个字节表示分配的大小
  • 返回指向第7字节开始的指针

因此,当您拨打free(ptr)时,分配器会在您的指针前6个字节检查签名。如果它没有找到签名,它会崩溃:)

+0

非常好的解释,谢谢。我知道有一个签名,但不确定具体情况。 – Lefteris 2011-05-16 06:22:17

2

行为未定义,很可能导致分段错误 - 这就是好案例。在最糟糕的情况下,它会破坏程序的内存并引发各种奇怪的错误和错误的输出。

8

如果free()的参数与以前通过malloc()和朋友分配的指针不匹配,则行为未定义。您很可能会在您的libc版本中遇到分段错误或失败的断言。

Offtopic:这是更好的,你不投的malloc()的结果C.

+0

感谢您的答案michael。我主要使用C++编码,我认为这是标准做法。我不知道C和malloc。请记住,谢谢。 – Lefteris 2011-05-16 06:26:47

2

在大多数实现中,这应该会导致某种致命错误。您只能释放分配的缓冲区的开始。

他们会在窗口(使用Visual Studio编译器)上得到的典型错误就像是“不是有效的堆指针”。在linux上,如phihag所述,通常会导致分段错误。在这两种情况下,这是一个运行时错误,通常会终止程序的执行。

2

行为是未定义的。我想你会得到一个segfault ...这是我在我的系统中尝试时得到的。

free()要求调用者传递由存储器分配器函数(如malloc())返回的地址。其他任何事情都会导致未定义的行为。