类
class Dummy
{
public:
int x;
Dummy(int y):x(y)
{
}
~Dummy()
{
std::cout<<"boom"<<std::endl;
}
};
功能
Dummy& getRef()
{
Dummy* temp = new Dummy(5);
return *temp;
}
致电
Dummy* get = &getRef();
std::cout<<get->x<<std::endl;
get->~Dummy();
我的目的是从函数中获取动态对象实例,然后将其传递给main的指针。
我的问题:
调用get->~Dummy();
后,指针Dummy* temp
是否还活着还是悬空?
我知道动态创建的对象不会被破坏,除非调用析构函数(即使它超出范围)但我不确定指针本身。
使用unique_ptr
可轻松克服此问题,但我想了解更多有关生命周期的信息。
答案 0 :(得分:3)
我知道除非调用析构函数,否则动态创建的对象不会被破坏。
这不准确。当某个对象被销毁时,析构函数会触发,除非有人有充分的理由手动触发它们(并且你不要这里)。他们不会煽动这种破坏。其他的事情(无论是什么踢出对象破坏,无论是范围退出,还是delete
等)。
是的,你正在泄露记忆。您的new
没有相应的delete
。存在内存泄漏的灵魂。如果您丢失了手动析构函数调用并使用
delete get;
你的代码将是合理的(虽然很奇怪,但不是)。
答案 1 :(得分:2)
指针只是内存中的一个位置。当您的函数getRef()
退出temp
变量时,该分配仍然存在。
您仍然可以从返回变量中获取地址。
delete get;
会破坏你的对象
如果调用代码没有删除该对象,则会发生内存泄漏。
明确地调用析构函数通常不明智。像脚本语言这样的一些实例需要这种东西,但很少见。
答案 2 :(得分:0)
您使用new
分配了内存,因此内存仅在您delete
(您不这样做)时才会释放。 pointee对象的析构函数不会解除分配任何内容。
您显式调用了pointee对象的析构函数,因此它被“销毁”但未解除分配。如果你然后delete
指针,那么析构函数将被调用两次,这是你不想要的。
当您打算使用placement new
在它以前占用的内存中构造一个新对象时,才显式调用析构函数。显式调用析构函数(get->~Dummy()
)后,指针仍指向有效的内存位置,尽管该位置没有构造对象。
答案 3 :(得分:0)
你的例子中发生了什么(虽然你不应该写这种代码):
(与新Dummy(5)一致),发生分配,在分配的空间内调用AND构造函数
直到get-&gt; ~Dummy()没有变化;似乎(虽然在这里我并非完全100%确定)从指针到引用和返回的所有转换都是无关紧要的,并且不会导致任何构造函数被调用(无论如何,你不应该&#39;做这些事情,至少为了便于阅读)
当调用get-&gt; ~Dummy()时,它调用析构函数,但不解除底层内存块的释放。在此之后,您可以拨打&#34; placement new&#34;与你的&#39;得到&#39;指针,在同一个分配的空间内创建一个不同的对象(并具有相同的内存地址),或者你可以释放内存块(使用any-your-library-new-uses-for-allocation),否则你会有内存泄漏(正如PhilCK所说)。
根据经验,你不应该明确地为你已经通过“&new”创建的对象调用析构函数,因为它具有非常特殊的含义(见上文);使用&#39;删除&#39;相反(&#39;删除&#39;将调用析构函数并释放底层内存块)。