char* x = malloc(512);
memset(x, 0, 513);
free(x);
这是为什么这个程序崩溃?这是说free(): invalid pointer: 0x0000000000614010
这没有任何意义,如果有的话它应该破坏程序的一些其他随机部分,因为它写入未定义的内存空间。为什么这个指针无效?
char* x = malloc(512);
memset(x, 0, 513);
free(x);
这是为什么这个程序崩溃?这是说free(): invalid pointer: 0x0000000000614010
这没有任何意义,如果有的话它应该破坏程序的一些其他随机部分,因为它写入未定义的内存空间。为什么这个指针无效?
您已经分配了512字节的内存,但正在向其写入513个字节。 free()
大概是检查内存区域是否仍然有效(如果它包含您写过的保护字节,则不会)。
我是新来的,但我希望我能回答这个问题,让您满意。
您正在通过覆盖分配的块的重要部分来激发未定义的行为。您正在删除该块上大小信息的第一个(高位字节),即由malloc
编写。大多数C标准库使用Doug Lea Malloc追加和prepends一些字节到您的块,它们包含大小和使用信息。通过覆盖这个,你实际上销毁了free()
调用成功所需的信息,并真正释放了malloc的内存。 malloc
的某些实现不会这样做,并为块对齐和大小保留一个“带外”表(其他位置,而不覆盖它),并且一些只是预先附加/追加该信息。正如我所说,你的程序崩溃,因为你覆盖了重要的信息,没有它,free()
就是不能做它应该做的事情。
堆分配器在分配内存之前和/或之后立即放置一些簿记信息是很常见的。你观察到的一个可能的解释是你已经覆盖了对内存分配器的操作至关重要的一些数据,可能是分配的块的大小或下一个可用空间的位置。
在任何情况下,在您分配的空间范围之外写入都是未定义的行为,并且可能发生任何事情。仅仅因为这是现在发生的事情并不意味着它会发生在不同的系统上,甚至在不同的时间在同一个系统上。相反,即使你没有看到错误,这并不意味着未定义的行为不会被调用。这是使用不安全语言的成本,例如C.
[鼻恶魔](http://catb.org/jargon/html/N/nasal-demons.html)! – ephemient