C++ 使用new分配内存会返回相同的内存地址

C++ 使用new分配内存会返回相同的内存地址,c++,C++,在实际场景中,ptr1应该无效,但因为编译器将相同的地址分配给 功能2 ptr1中的arr[p]仍然有效。为什么不发生这种情况?一旦您删除了特定地址的内存,内存管理器就完全可以在您下次请求新内存时重新使用该地址。实际上,这是内存管理器使用的一种非常常见的优化。它们跟踪最近释放的块,并将它们交回下一个请求该大小的块的客户端 另一种方法是考虑如果没有重新使用地址,将会发生什么。如果这种情况发生,那么在经过足够的分配/解除分配周期后,最终将没有地址空间了。事实上,如果重用从未发生过,那么释放内存就毫无

在实际场景中,ptr1应该无效,但因为编译器将相同的地址分配给

功能2 ptr1中的arr[p]仍然有效。

为什么不发生这种情况?一旦您删除了特定地址的内存,内存管理器就完全可以在您下次请求新内存时重新使用该地址。实际上,这是内存管理器使用的一种非常常见的优化。它们跟踪最近释放的块,并将它们交回下一个请求该大小的块的客户端

另一种方法是考虑如果没有重新使用地址,将会发生什么。如果这种情况发生,那么在经过足够的分配/解除分配周期后,最终将没有地址空间了。事实上,如果重用从未发生过,那么释放内存就毫无意义了。所以,是的,当您释放内存时,该内存地址将被重新使用

Function1 ->   
arr[p] = new X  
ptr1 = arr[p]  
using ptr1 

Function2 ->   
ptr2 = arr[p]  
delete ptr2  
arr[p] = new X ( new data) 
这将分配足够的内存来保存abc对象并指向该地址(假设地址为0x1234)。因此,A包含值0x1234

删除一条

将释放该内存(这意味着内存将返回到空闲存储)。但A仍然包含该内存地址的值,即0x1234

删除同一个指针两次会导致未定义的行为,这只是第二次删除不属于您的内存时才会发生的

这就是你为什么这么做的原因

abc *A = new abc ;

删除内存后。

释放的内存不再使用。内存管理器可以根据需要使用堆—分配下一个可用空间—即您刚才实际释放的空间。

这是因为您正在删除指针。不要删除它们—您将看到差异

A= NULL;
在这一步中,输出可能仍然是相同的-因为分配器有以前分配给
A
的内存供现在使用,所以它可以将其用于
B

abc *B = new abc ;
cout<< static_cast<void*>(B) << endl ;
删除B;

您能提供输出吗?0x11d5a010 0x11d5a010 0x11d5a010 0x11d5a010 0x11d5a010“即使我在删除后分配空值”-嗯?没关系,“连A和B的地址都一样”这只是巧合。(可能你只有一块堆内存……只是开玩笑而已)。当指针指向的内存被释放时,指针不会发生什么特别的事情——程序员有责任不使用无效指针。它“仍然有效”是一种特殊形式的未定义行为。a和B的地址是相同的。是的,我知道。这就是你在问题中说的,不是吗。我的回答解释了为什么,@AvinashKumar您打印的是存储在
A
B
中的地址,而不是
A
B
的地址。由于您对旧块调用了
delete
,分配器可以轻松地重用它。@DavidHeffernan我更新了场景,请回答我回答了您提出的问题。如果你想问一个新问题,尽管问吧。首先,我们能了解一下你问的问题吗。这不是我的问题,我知道。是的,我知道我刚刚解释了一些与你的情景有关的额外内容。
abc *A = new abc ;
abc *B = new abc ;
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 ;