正在理解智能指针,但出现错误:未分配正在释放的指针
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;
}
我在这里试图做的是访问原始指针,但通过智能指针。它打印"你好世界"很好,当我注释掉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()
析构函数尝试再次释放它。
来自shared_ptr::reset()
:
如果
*this
已经拥有一个对象,并且是最后一个拥有该对象的shared_ptr
,则将通过拥有的deleter
销毁该对象。
您的p.reset((删除了B对象,因为它对拥有它的变量a一无所知,并且您没有手动增加p的引用计数(这在shared_ptr中是不可能的,因为它被设计为只通过复制shared_ptr对象来共享指针(。
你在这里试图用reset(ptr(做的是未定义的行为:
如果ptr指向的对象已经拥有,则函数结果处于未定义的行为。
https://en.cppreference.com/w/cpp/memory/shared_ptr/reset
- 将指针分配给另一个指针时会发生什么情况?
- C++将一个指针分配给另一个指针时执行的类型检查
- 我似乎无法为指针分配一个数组,然后更改数组的内容
- C++为 void 指针分配一个字符串
- 当我在 C++ 中将派生类的指针分配给指针时,地址会更改
- MPI 集合通信中的指针分配
- 函数指针分配在创建 DLL 后导致错误
- 通过双指针分配指针
- C++编译时使用 constexpr 字符数组指针分配静态数组?
- 我可以直接为指针分配地址吗?如果是,如何做到这一点
- 为什么为char指针分配内存不会截断char序列
- C++指针分配字符数组的地址
- 将 void 指针分配给另一个 void 指针
- 如何将不同的成员函数指针分配给注册类的不同实例?
- 如何为指针分配特定的内存地址?
- C++ - 无法将顶部常量指针分配给另一个非常量指针
- 将指针分配给另一个指针时会发生什么情况?
- 为指向C++中的对象/对象的指针分配堆内存
- 将指针分配给字符串变量中包含的地址
- 当直接分配时,为什么此功能指针分配起作用,而不是与有条件的操作员一起使用