5

我的问题很简单。假设我们有:

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

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

4

5 回答 5

10

您的程序可能会崩溃:free() 操作在 C 中实际上非常简单,但仅适用于原始分配的地址。

典型的内存分配器像下面的伪代码一样工作:

  • 要求分配 64 个字节
  • 分配器分配 70 个字节(多 6 个字节)
  • 前 2 个字节设置为“签名”,分配器识别的一种模式,用于标识他分配的内存
  • 接下来的 4 个字节表示分配的大小
  • 返回指向第 7 个字节开头的指针

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

于 2011-05-16T06:12:22.060 回答
8

如果 to 的参数与free()先前通过 和friends 分配的指针不匹配malloc(),则行为未定义。您很可能会在您的libc.

题外话:最好不要malloc()在 C中转换结果。

于 2011-05-16T06:10:13.407 回答
2

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

于 2011-05-16T06:08:26.890 回答
2

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

您在 Windows(使用 Visual Studio 编译器)上遇到的典型错误类似于“不是有效的堆指针”。在 linux 上,正如上面 phihag 所说,它通常会导致分段错误。在这两种情况下,它都是运行时错误,通常会终止程序的执行。

于 2011-05-16T06:12:32.277 回答
2

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

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

于 2011-05-16T06:22:01.080 回答