C ++在向量中存储对象(带有指向另一个对象的指针)

时间:2013-05-27 15:17:14

标签: c++ pointers vector

我想将MyClass存储在vector中。 MyClass有指向InnerClass的指针和MyClass的ind析构函数我想为以前分配的InnerClass对象释放内存。

这是我的代码:

#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 ***

问题是:为什么我会收到此错误?

1 个答案:

答案 0 :(得分:0)

您尚未正确实现复制构造函数,并且您尚未为MyClass提供分配运算符。现在my是循环的局部变量,所以一旦循环迭代结束就会调用析构函数。但是,带有指向已释放对象的指针的MyClass将被推送到向量cont中。稍后将调用此实例的析构函数(当调用向量的析构函数时)并将尝试再次释放内存。

在处理动态内存时,正确实现赋值运算符和复制构造函数的方法就是分配新对象并复制内容。