[英]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.