2013-05-27 56 views
0

我想存儲在MyClass的矢量。 MyClass具有指向InnerClass的指針和MyClass的ind析構函數我想爲先前分配的InnerClass對象釋放內存。C++存儲對象(與指針到另一個對象)在矢量

這裏是我的代碼:

#include <iostream> 
#include <algorithm> 
#include <vector> 
#include <map> 

#define PB push_back 
#define MP make_pair 

using namespace std; 

int cnt; 
map<int, int> m; 

void mark(int id) { 
    if(m.find(id) != m.end()) 
     cout << "ERROR! " << id << " was marked before" << endl; 
    m[id] = 1; 
} 

void unmark(int id) { 
    if(m[id] != 1) 
     cout << "ERROR! " << id << " was not marked before" << endl; 
    m[id] = 0; 
} 

void look() { 
    cout << endl; 
    for(int i=0;i<cnt;++i) { 
     cout << i << ": " << m[i] << endl; 
    } 
    cout << endl; 
} 

class InnerClass { 
    public: 
    InnerClass(int _id) { 
     cout << "InnerClass::InnerClass(int) called (#" << _id << ")" << endl; 
     id = _id; 
    } 
    InnerClass(const InnerClass& org) { 
     cout << "InnerClass::InnerClass(const InnerClass&) called (#" << org.id << ")" << endl; 
     id = org.id; 
    } 
    int getID() { 
     return id; 
    } 
    private: 
    int id; 
}; 

class MyClass { 
    public: 
    MyClass(InnerClass* _inner) { 
     id = cnt++; 
     mark(id); 
     cout << "MyClass::MyClass(InnerClass*) called (#" << id << ")" << endl; 
     inner = _inner; 
    } 
    MyClass(const MyClass& org) { 
     id = cnt++; 
     mark(id); 
     cout << "MyClass::MyClass(const MyClass&) called (#" << id << " <- #" << org.id << ")" << endl; 
     inner = new InnerClass(org.inner->getID()); 
    } 
    ~MyClass() { 
     unmark(id); 
     cout << "MyClass::~MyClass() called (#" << id << ")" << endl; 
     delete inner; 
    } 
    private: 
    InnerClass* inner; 
    int id; 
}; 

bool cmp(const pair<double, MyClass > &p, const pair<double, MyClass > &r) { 
    return p.first < r.first; 
} 

int main() { 
    vector<pair<double, MyClass> > cont; 
    int n = 3; 
    for(int i=0;i<n;++i) { 
     InnerClass* inner = new InnerClass(i); 
     MyClass my(inner); 
     cont.PB(MP((double)i, my)); 
    } 
    look(); 
    cout << "Sorting" << endl; 
    sort(cont.begin(), cont.end(), cmp); 
    return 0; 
} 

下面是輸出:

InnerClass::InnerClass(int) called (#0) 
MyClass::MyClass(InnerClass*) called (#0) 
MyClass::MyClass(const MyClass&) called (#1 <- #0) 
InnerClass::InnerClass(int) called (#0) 
MyClass::MyClass(const MyClass&) called (#2 <- #1) 
InnerClass::InnerClass(int) called (#0) 
MyClass::MyClass(const MyClass&) called (#3 <- #2) 
InnerClass::InnerClass(int) called (#0) 
MyClass::~MyClass() called (#2) 
MyClass::~MyClass() called (#1) 
MyClass::~MyClass() called (#0) 
InnerClass::InnerClass(int) called (#1) 
MyClass::MyClass(InnerClass*) called (#4) 
MyClass::MyClass(const MyClass&) called (#5 <- #4) 
InnerClass::InnerClass(int) called (#1) 
MyClass::MyClass(const MyClass&) called (#6 <- #5) 
InnerClass::InnerClass(int) called (#1) 
MyClass::MyClass(const MyClass&) called (#7 <- #6) 
InnerClass::InnerClass(int) called (#1) 
MyClass::MyClass(const MyClass&) called (#8 <- #3) 
InnerClass::InnerClass(int) called (#0) 
MyClass::~MyClass() called (#3) 
MyClass::~MyClass() called (#6) 
MyClass::~MyClass() called (#5) 
MyClass::~MyClass() called (#4) 
InnerClass::InnerClass(int) called (#2) 
MyClass::MyClass(InnerClass*) called (#9) 
MyClass::MyClass(const MyClass&) called (#10 <- #9) 
InnerClass::InnerClass(int) called (#2) 
MyClass::MyClass(const MyClass&) called (#11 <- #10) 
InnerClass::InnerClass(int) called (#2) 
MyClass::MyClass(const MyClass&) called (#12 <- #11) 
InnerClass::InnerClass(int) called (#2) 
MyClass::MyClass(const MyClass&) called (#13 <- #8) 
InnerClass::InnerClass(int) called (#0) 
MyClass::MyClass(const MyClass&) called (#14 <- #7) 
InnerClass::InnerClass(int) called (#1) 
MyClass::~MyClass() called (#8) 
MyClass::~MyClass() called (#7) 
MyClass::~MyClass() called (#11) 
MyClass::~MyClass() called (#10) 
MyClass::~MyClass() called (#9) 

0: 0 
1: 0 
2: 0 
3: 0 
4: 0 
5: 0 
6: 0 
7: 0 
8: 0 
9: 0 
10: 0 
11: 0 
12: 1 
13: 1 
14: 1 

Sorting 
MyClass::MyClass(const MyClass&) called (#15 <- #14) 
InnerClass::InnerClass(int) called (#1) 
MyClass::~MyClass() called (#15) 
MyClass::MyClass(const MyClass&) called (#16 <- #12) 
InnerClass::InnerClass(int) called (#2) 
MyClass::~MyClass() called (#16) 
MyClass::~MyClass() called (#13) 
ERROR! 15 was not marked before 
MyClass::~MyClass() called (#15) 
ERROR! 16 was not marked before 
MyClass::~MyClass() called (#16) 
*** glibc detected *** ./vector-class: double free or corruption (fasttop): 0x000000000194c6b0 *** 

的問題是:爲什麼會出現這樣的錯誤?

+0

你不是以下三個規則。你應該只使用一個智能指針。 – chris

+0

@chris更好:他們不應該使用任何東西。 'InnerClass內部'將工作得很好。 –

+0

請勿使用'id = _id;'。改用成員初始化程序(請參閱http://stackoverflow.com/q/1711990/46642)。如果這是你的書是如何教你寫的構造函數,你可能不應該把太多信任它,因爲你最終將學習編寫C++的一個很煩人的,非常有限的,而且非常脆弱的方式。我們在這裏列出了很好的書:http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list。 –

回答

0

您沒有正確執行拷貝構造函數,你也沒有提供MyClass的一個assignement操作。現在my是循環的局部變量,所以它的析構函數在循環迭代結束後被調用。然而,隨着指針已釋放對象MyClass在矢量cont推。稍後,此實例的析構函數也將被調用(當調用向量的析構函數時),並且將嘗試再次釋放內存。

正確的方式來實現賦值操作符和拷貝構造函數與動態內存打交道時喜歡你做的是分配一個新對象,並複製的內容。

相關問題