class abc {
int x ;
};
int main()
{
abc *A = new abc ;
cout<< static_cast<void*>(A) << endl ;
delete A ;
cout<< static_cast<void*>(A) << endl ;
abc *B = new abc ;
cout<< static_cast<void*>(B) << endl ;
delete B ;
cout<< static_cast<void*>(B) << endl ;
return 0;
}
为什么它打印相同的地址,即使我删除了旧内存 即使我在删除后指定null,它也会打印相同的地址。
即使A和B的地址相同。
实时情景:
Function1 ->
arr[p] = new X
ptr1 = arr[p]
using ptr1
Function2 ->
ptr2 = arr[p]
delete ptr2
arr[p] = new X ( new data)
在实际情况中,ptr1应该无效,但由于编译器将相同的地址分配给
函数2中的arr [p] ptr1仍然有效。
答案 0 :(得分:6)
为什么不发生这种情况?一旦删除了特定地址的内存,内存管理器完全可以在下次请求新内存时重新使用该地址。实际上,这是内存管理器使用的非常常见的优化。他们跟踪最近释放的块并将它们交还给下一个请求该块大小的客户端。
另一种看待这种情况的方法是考虑如果从未重用过释放的地址会发生什么。如果发生这种情况,那么最终,在足够的分配/解除分配周期之后,将不会留下任何地址空间。实际上,如果重复使用从未发生过,那么在释放内存方面根本就没有意义。所以是的,确实期望在释放内存时,将重新使用该内存地址。
答案 1 :(得分:2)
这是因为您正在删除指针。如果不删除它们,您将看到差异。
abc *A = new abc ;
abc *B = new abc ;
答案 2 :(得分:1)
abc *A = new abc ;
这将分配足够的内存来保存abc对象并使A指向该地址(假设地址为0x1234)。因此,A包含值0x1234。
删除A;
将释放该内存(这意味着内存将返回到免费存储)。但是A仍然包含该存储器地址的值,即0x1234。
两次删除相同的指针会导致未定义的行为,这只是第二次删除不属于你的内存时这个事情的结果。
这就是你做的原因
A= NULL;
删除内存后。
答案 3 :(得分:1)
你释放的记忆不再使用了。内存管理器可以根据需要使用堆 - 分配下一个可用空间 - 即之前实际释放的空间。
答案 4 :(得分:0)
abc *A = new abc ;
cout<< static_cast<void*>(A) << endl ;
这是第一个输出。
delete A ;
cout<< static_cast<void*>(A) << endl ;
虽然它在delete
之后,A
的值保持不变。 delete
做了什么:1。调用A
的析构函数(在这种情况下是微不足道的)和2.通知内存分配器,为A
分配的内存现在是空闲的,可以使用用于其他目的。
abc *B = new abc ;
cout<< static_cast<void*>(B) << endl ;
可能在此步骤中输出仍然相同 - 因为分配器具有先前为A
分配的内存以供现在使用,它可以将其用于B
。
delete B ;
cout<< static_cast<void*>(B) << endl ;
与A
相同。