0

我想将 MyClass 存储在向量中。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 ***

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

4

1 回答 1

0

您没有正确实现复制构造函数,也没有为 MyClass 提供赋值运算符。Nowmy是循环的局部变量,因此一旦循环迭代完成,就会调用它的析构函数。然而,一个MyClass指向已释放对象的指针被推入向量中cont。稍后这个实例的析构函数也将被调用(当向量的析构函数被调用时)并且将尝试再次释放内存。

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

于 2013-05-27T15:22:36.200 回答