共享指针的双自由度或损坏
double free or corruption with shared pointers
所以我的问题的本质是:
//Big.h
class Big{
public:
int a, b;
};
//Mini.h
class Big;
class Mini{
public:
Mini(float a, shared_ptr<Big> ptb):ma(a), me(-a), ptb(ptb){};
float ma, me;
shared_ptr<Big> ptb;
};
//main
int main(){
std::list<Mini> lm;
if(true){ //Or some sub function or rutin
Big big; big.a = 100; big.b = 200;
Mini derp(5, shared_ptr<Big>(&big));
lm.push_front(derp);
}
//Do something
};
编译得很好,但是当退出main(在完整的程序中这只是一个子函数)时,它给出了一个"双自由或损坏"
我怀疑shared_ptr
到big
在某个时候被释放,然后在退出main时再次被释放,但我不确定,也不知道如何修复它。有人能给我解释一下这个错误的原因吗?
我认为我必须NULL
的指针,但我不知道在哪里。或者我只是用错了智能指针之类的?
谢谢
您正在使用指向堆栈上现有对象的指针构建shared_ptr
。不要那样做;这不是shared_ptr
的使用方式。普通的堆栈对象永远不应该被删除或释放。它指向的对象应该在堆上,即使用new
或等效的方法创建。
创建shared_ptr
的推荐方法是通过make_shared
:
auto p = make_shared<Big>();
或传统方式:
shared_ptr<Big> p(new Big);
由shared_ptr
管理的对象必须在动态范围内构造,即分配给new
。
Big big;
big.a = 100;
big.b = 200;
Mini derp(5, shared_ptr<Big>(&big));
在这里,你把一个指向在自动作用域内构造的对象的指针推入shared_ptr
。shared_ptr
现在认为它拥有这个对象,并且它可以决定何时将它交给delete
。
但是当自动作用域中的对象超出作用域并被销毁时,这将使shared_ptr
非常非常悲伤。
使用new
来构造这个对象,而不是在自动作用域中构造。
shared_ptr
指向一个堆栈对象。不能释放堆栈对象。以下是如何使用shared_ptr
:
auto big = std::make_shared<Big>();
big->a = 100;
big->b = 200;
Mini derp(5, big);
要纠正程序,需要在堆上分配Big
对象。
if(true){ //Or some sub function or rutin
auto big_shared_ptr = std::make_shared<Big>();
big->a = 100; big->b = 200;
Mini derp(5, big_shared_ptr);
lm.push_front(derp);
}
这样,当if(true)块返回以及shared_ptr被清理时,变量不会被销毁——这将导致double free。
相关文章:
- 为什么会发生堆损坏
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 平均图像时图像损坏
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 为什么C中的通用链表中存储的数据已损坏
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- C++双重释放或损坏(out)
- 捕获标准输出以压缩并使用 CTRL-C 中断会给出损坏的 zip 文件
- 使用全局声明的向量时,C++双重释放错误/损坏
- 变量周围的堆栈'...'已损坏
- 运行时检查失败 #2 变量"A"周围的堆栈已损坏
- 检测到堆损坏:在正常块 c++ 动态 2D 数组之后
- 删除字符串后C++检测到堆损坏
- 两个垫子的 OpenCV 数据是相同的,但使用 Mat::at 检索时的值已损坏
- 我可以写入关闭的套接字并强制纠正损坏的管道错误吗?
- 损坏的结构字符数组 - sqlite C++
- 运行时检查失败 #2 - 变量"e"周围的堆栈已损坏。发生
- zlib 膨胀在使用小缓冲区时会损坏
- std::remove_if/find_if:双自由度或损坏
- 共享指针的双自由度或损坏