-2

在 C 中,我在编写以下示例时遇到了错误:

int *pointer;
int i = 0;
pointer = malloc(10 * sizeof(int));
pointer[i - 1] = 4;

显然i是一个负索引pointer

即使更改了不正确的片段内存,为什么仅在free(pointer)[稍后在代码中] 时才触发错误?错误是:double free or corruption (out)

编辑:使用的编译器是gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

4

2 回答 2

5

大多数(如果不是全部)内存管理器(例如:malloc)会在您请求的内存周围分配额外的数据。这个额外是为了帮助内存管理器通过将一些自己的数据添加到分配中来管理各种分配。当你做你的负索引时,你覆盖了这个额外的数据。它本身并不是无效的内存,因此 CPU 无法防御它,但是当 malloc 看到它的数据被破坏时,它确实会抱怨。这将发生在 free() 上。

于 2013-02-10T05:32:40.677 回答
1

从根本上说,访问pointer[-1]您所做的方式会产生未定义的行为;理论上,任何事情都可能发生。但在实践中,对于您收到的特定错误消息有一个很好的解释。

回想一下,malloc必须将分配的内存块的大小保存在某处,这样free才能正常工作。在某些系统上——你的系统似乎就是其中之一——这些信息存储在内存中,就在malloc返回的地址之前。(如果您想了解系统的实现,打印出该值可能会很有趣。)

当您覆盖了那块内存时,您使系统内部处于不一致的状态,导致malloc发现时报告错误。当然,这种发现最有可能发生的时间是调用有关该内存区域的内存管理函数时。(下一次调用时会检测到一些损坏,但这通常需要更刻意的努力才能实现。)调用应该会给你一个类似的错误消息。freefreemallocmallocrealloc

于 2013-02-10T05:37:25.233 回答