我正在运行一个小样本。我的代码是
int main()
{
char * mymem = new char[8];
//1
memcpy(mymem+8,"hello",5); //this cause heap corruption
//2
mymem[32]='a'; //this doesn't cause heap corruption
//3
delete [] mymem;
return 0;
}
在上面的代码中,如果我执行1,那么我在删除即3时遇到堆损坏, 但如果执行2然后我不会在删除时得到任何堆损坏,即3.我很想知道为什么会发生这种情况,因为在这两种情况下我都试图在分配的内存之外写入。
答案 0 :(得分:2)
行为未定义,但我将尝试回答这个问题并解释为什么在这种情况下第一次访问会导致堆损坏,但第二次访问没有堆损坏。
当您调用new[]
或new
时,为了将额外内存用作guard bytes
,某些运行时库将分配比请求更多的内存。额外内存量通常只有几个字节。
保护字节的目的是检测发出delete[]
时这些字节的值是否发生变化。如果在发生重新分配时保护字节发生了变化,那么系统可以检测到你做错了什么。
很可能,运行时检测到您覆盖了保护字节,因此可以标记您“堆损坏”。但是,当您写入mymem[32]
时,它超出了分配的保护字节(我非常怀疑系统将32字节分配为保护字节),因此运行时无法检测到您在分配的空间之外写入。 / p>
答案 1 :(得分:1)
在两种情况下,您都在分配的内存之外编写,这会调用未定义的行为。一旦有UB,您可能会得到预期或意外的结果。