[英]Understanding smart pointers but error: pointer being freed was not allocated
我正在尝试了解智能指针,并具有以下代码:
#include <iostream>
#include <string>
#include <memory>
using namespace std;
struct B
{
string hello() { return "hello world"; }
};
class A
{
private:
B* a;
public:
A() { a = new B; }
~A() { delete a; a = nullptr; }
B* get() { return a; }
};
int main(int argc, const char * argv[]) {
A a;
shared_ptr<B> p(a.get());
cout << p->hello() << endl;
p.reset();
return 0;
}
我在这里想要做的是通过智能指针访问原始指针。 它可以很好地打印“ hello world”,并且在注释掉A的析构函数时没有错误。但是,当我取消注释时,出现以下错误:
test(9758,0x7fff738d9300) malloc: *** error for object 0x1001053a0: pointer
being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
这里发生了什么? 当shared_ptr p超出范围或重置(重置为nullptr)时,它正在调用析构函数吗? p如何处理不删除A :: a引起的内存泄漏?
我了解智能指针通常会处理新对象,并且这种情况可能不经常使用,但是我想尝试学习这一点。
当shared_ptr p超出范围或重置(重置为nullptr)时,它正在调用析构函数吗?
对,就是这样。
p如何处理不删除A :: a引起的内存泄漏?
p
认为它拥有对象,因此将其删除。 没有泄漏。 但是a
也认为它也拥有该对象,因此它尝试第二次删除它并崩溃。
我了解智能指针通常会处理新对象,并且这种情况可能不经常使用,但是我想尝试学习这一点。
完全没有使用这种情况,因为正是由于这个原因,您不能让多个对象同时拥有相同的内存。
正确的解决方案是使class A
内部使用shared_ptr
:
class A {
private:
shared_ptr<B> b;
public:
A() { b.reset(new B); }
shared_ptr<B> get() { return b; }
};
int main(int argc, const char * argv[]) {
A a;
shared_ptr<B> p = a.get();
cout << p->hello() << endl;
p.reset();
return 0;
}
或者干脆不拥有未直接分配给您的原始指针的所有权:
int main(int argc, const char * argv[]) {
A a;
B *p = a.get();
cout << p->hello() << endl;
return 0;
}
使用智能指针的全部要点是明确谁拥有什么以及如何转移所有权。 您的例子违反了这一点。
A a;
和shared_ptr<B> p(a.get());
指向内存中相同的已分配B
对象。 p.reset()
破坏该B
对象,然后将~A()
的析构函数尝试再次释放它。
如果
*this
已经拥有一个对象,并且它是拥有它的最后一个shared_ptr
,则该对象将通过拥有的deleter
销毁 。
您的p.reset()删除了B对象,因为它对拥有它的变量一无所知,并且您没有手动增加p的引用计数(对于shared_ptr来说这是不可能的,因为它被设计为仅通过复制共享一个指针) shared_ptr对象)。
您在此处尝试使用reset(ptr)进行的操作是未定义的行为:
如果ptr指向的对象已经拥有,则该函数将导致未定义的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.