我知道在C ++中使用智能指针最好/更安全,以确保我们永远不会错过释放/删除分配的内存的机会。现在,我最近在有关C ++中智能指针的讲座中遇到了以下问题。这是示例:
void test_pointer(void)
{
typedef std::shared_ptr<MyObject> MyObjectPtr;
MyObjectPtr p1; // Empty
{
MyObjectPtr p2(new MyObject());
p1 = p2;
}
}
现在,我知道std:shared_ptr
将在其最后一次引用完成后被销毁,即,我们退出函数p1
之后将被销毁。但是最后的警告是关于悬挂的参考,这让我感到困惑:
MyObjectPtr* pp = new MyObjectPtr(new MyObject());
[注提到,如果在函数中声明了它,则它是一个悬空引用,这将防止删除std::shared_ptr
。这是为什么?我们正在使用智能指针,所以我们永远都不会结束这种情况吗?
我刚刚意识到这一点(如果我错了,请纠正我):
我们正在使用指向std::shared_ptr
的原始指针,该指针从未被释放,这是导致问题的原因。它永远不会被释放。并且由于这是在函数中发生的,因此它还可以防止p1被破坏。
怎么来?我们正在使用智能指针,所以我们永远都不会结束这种情况吗?
您不是。在这里:
MyObjectPtr* pp = new MyObjectPtr(new MyObject());
您正在使用原始指针指向类型为智能指针的对象。但这并不会影响您手动分配什么样的对象并将其保留在raw pointer中-您必须手动管理该对象的生存期。或使用智能指针。
您可以制作一个小程序,向您显示您的位置以及何时创建和销毁对象,如下所示>
显示,然后创建一个指向#include <memory> #include <iostream> struct MyObject{ MyObject(){ std::cout << "created\n"; } ~MyObject(){ std::cout << "destroyed\n"; } }; void test_pointer(void) { std::cout<< "In the function scope\n"; typedef std::shared_ptr<MyObject> MyObjectPtr; MyObjectPtr p1; { std::cout<< "In inner scope\n"; MyObjectPtr p2(new MyObject()); p1 = p2; } std::cout<< "In the function scope\n"; } int main(){ test_pointer(); }
现在,当您输入功能范围时在功能范围中
shared_ptr
的nullptr
,然后输入inne范围和控制台显示在功能范围中] >然后创建另一个shared_ptr
,但是这次ptr2
指向new创建的对象,该对象返回了shared_ptr
的构造函数使用的原始指针。[在您将ptr1
指向p1 = p2
(共享拥有者船)指向同一个对象之后,则保留了内部作用域,因此p2
已被破坏,但该对象仍然存在,因为它指向p1
。
现在控制台显示“在函数作用域”
,这确保对象在离开内部作用域后仍保持活动状态。最后离开函数作用域,然后对象被破坏,因为p1
被破坏,因为创建它的作用域已经消失。