我正在尝试一个一个地破坏 shared_ptr,
我不知道那是什么意思,但是...
myPtr.~__shared_ptr();
永远,永远,永远这样做。
您正在为一个自动对象运行析构函数,即一个存在于堆栈中的对象,当它超出范围时将被编译器自动销毁。通过手动销毁它会导致它被销毁两次。你不能结束一个物体的生命两次,它不是詹姆斯邦德,它只存在一次。
两次销毁同一个对象是未定义的行为。这意味着可能会发生奇怪的事情。问你为什么从一个行为未定义的程序中得到奇怪的结果是浪费时间。当你有未定义的行为时会发生奇怪的事情,因为你有未定义的行为。任何事情都有可能发生。你应该庆幸这只是奇怪的,而不是灾难性的。
该标准在 12.4 [class.dtor] 中特别指出了这种确切的情况是未定义的行为:
一旦为对象调用析构函数,该对象就不再存在;如果为生命周期已结束的对象调用析构函数(3.8),则行为未定义。[示例:如果自动对象的析构函数被显式调用,并且随后以通常会调用对象的隐式销毁的方式留下块,则行为未定义。——结束示例]
更糟糕的是,您正在为基类运行析构函数,myPtr
因此您只破坏了对象的一部分。这意味着您有一个对象,其中一部分已死,一部分还活着,然后在范围结束时,它的一部分又被杀死了。在任何情况下,这都不可能是正确的做法。曾经。
我希望在最终销毁时它将 use_count() 设置为 0 并为整数释放内存。似乎这一切都没有发生。
你的结论是错误的。它可能正在发生,但是如果对象被销毁并且内存被释放,那么试图查看它会产生无意义的结果。你不能问僵尸它的名字是什么,它会回答“BRAINZZZZ!” 而不是告诉你任何有用的东西。吃掉你的大脑。现在你死了。不要玩僵尸。
此外,正如 Neil Kirk 上面评论的那样,这也是错误的:
int * val = new int(5);
std::shared_ptr<int> myPtr = std::make_shared<int>(*val);
您int
在堆上创建一个,然后在堆上创建它的副本,该副本将由一个shared_ptr
. shared_ptr
拥有一个与没有拥有int
相同值*val
但没有拥有的值,val
因此这将是内存泄漏。您可能打算这样做:
int * val = new int(5);
std::shared_ptr<int> myPtr(val);
或更可能的是:
int val = 5;
std::shared_ptr<int> myPtr = std::make_shared<int>(val);