在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
答案 0 :(得分:5)
大多数(如果不是所有)内存管理器(例如:malloc)都会在您请求的内存周围分配额外的数据。这个额外的工作是通过将一些自己的数据添加到分配中来帮助内存管理器管理各种分配。当你做了负面索引时,你覆盖了这些额外的数据。它本身并不是无效的内存,因此CPU无法防范它,但是当malloc看到它的数据已被堵塞时,它确实会抱怨。这将发生在free()上。
答案 1 :(得分:1)
从根本上说,以你的方式访问pointer[-1]
会产生未定义的行为;理论上,任何都可能发生。但实际上,对于你得到的特定错误信息有一个很好的解释。
回想一下,malloc
必须在某处保存已分配的内存块的大小,以便free
可以正常工作。在某些系统上 - 似乎你的系统就是其中之一 - 这些信息存储在malloc
返回的地址之前的内存中。 (如果你想了解你的系统的实现,打印出这个值可能会很有趣。)
当你覆盖了那块内存时,你使malloc
- free
系统的内部处于不一致的状态,导致free
在发现错误时报告错误。当然,最有可能发生此类发现的时间是关于此内存区域调用内存管理功能的时间。 (下次调用malloc
时会检测到一些malloc
个损坏,但这通常需要更多刻意努力才能实现。)调用realloc
会给出类似的错误消息。