簡體   English   中英

shared_ptr C ++的雙重刪除錯誤

[英]Double deletion error with shared_ptr C++

我有以下課程設計:

struct compare{
template <typename T>
bool operator()(const T& a, const T&b){ return *a < *b;}
};

class Trans;

typedef set<shared_ptr<Trans>, compare > TransPointerSet;

class Place{

  // other data members
 TransPointerSet nextTrans;

public:

  // constructor and other methods including overloaded < operator
  void insertNextTrans(shared_ptr<Trans> t){ nextTrans.insert(t); }
  void removeNextTrans() { nextTrans.clear(); }

};

typedef set<shared_ptr<Place>, compare > PlacePointerSet;

class Trans{

//other data members
PlacePointerSet inPlaces;
PlacePointerSet outPlaces;

public:

//constructor and others including overloaded < operator
void insertInPlace(shared_ptr<Place> p){ 
     inPlaces.insert(p); 
     p->insertNextTrans(shared_ptr<Trans>(this)); }
void insertOutPlace(shared_ptr<Place> p){ //body }
void print() cosnt { //body }

};

class Net{
TransPointerSet acts;
//other data members
public:
//constructor and others
};

這是我測試類是否正常工作的主要方法。

int main()
{
 shared_ptr<Place> p1 = make_shared<Place>();
shared_ptr<Place> p2 = make_shared<Place>();
shared_ptr<Trans> t = make_shared<Trans>();
t->insertInPlace(p1);
t->insertOutPlace(p2);
t->print();
}

問題是在成功編譯后,在t-> print()正常工作后,它最終會出現“雙重釋放或損壞(fasttop)錯誤”。 我意識到錯誤在於首先通過將p1作為t-> inPlaces的成員而創建的循環依賴關系,該循環將t作為p1的成員插入。 但是我需要雙向鏈接。 另外,我嘗試通過t-> print()之后的方法來重置Place類中nextTrans的每個成員,但是由於指針位於集合中而無法正常工作。 那么,有人可以提出任何解決此問題的方法嗎?

這是因為你不能做一個共享指針this就是這樣。 通過這樣做,您現在有了兩個共享的指向Trans實例的指針,它們都指向同一個實例,但是具有各自的引用計數器。 這意味着它們都將嘗試delete指針。

您需要使用std::enable_shared_from_this 鏈接的參考頁有一個很好的例子說明您的問題。

Trans::insertInPlace()這一行:

p->insertNextTrans(shared_ptr<Trans>(this)); 

創建指向同一對象的單獨的,不相關的共享指針。 您需要為Trans類使用std::enable_shared_from_this

class Trans: public std::enable_shared_from_this {
    // ....
};

然后在Trans::insertInPlace()

p->insertNextTrans(shared_from_this());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM