1

有人可以告诉我以下代码有什么问题吗?我正在尝试使用包含节点 id 和指向其邻居的指针向量的类 Node 来实现一个图。这是我的代码的简短版本:

#include<vector>
#include<iostream>

using namespace std;


class N {
public:
    int i;
    vector<N*> v;
    N(int i) {
        this->i = i;
    };
};

int init(N* n1) {
    N n2(2);
    cout << "pointer " << &n2 << endl;
    n1->v.push_back(&n2);
};

int main() {
    N n1(1);
    init(&n1);
    cout << n1.i << endl;
    cout << "pointer " << n1.v[0] << endl;
    cout << n1.v.at(0)->i << endl;
    return 0;
};

问题是调用init函数后,节点n2似乎不存在了。

谢谢你的帮助。

4

3 回答 3

5

因为是局部变量,函数调用n2后会被释放。init因此在init函数调用之后,位于其先前地址的内容是未定义的。

要解决此问题,请考虑使用new运算符:

int init(N* n1) {
    N* n2 = new N(2);
    cout << "pointer " << n2 << endl;
    n1->v.push_back(n2);
};

或者干脆

int init(N* n1) {
    n1->v.push_back(new N(2));
};

由于您添加的实例是由new操作符创建的,因此您需要使用delete操作符释放它们的内存(例如 inN的析构函数):

~N() {
  for (int i = 0; i < v.size(); ++i) {
    delete v[i];
  }
  v.clear();
}
于 2013-06-27T20:44:42.103 回答
1
int init(N* n1) {
    N n2(2);
    cout << "pointer " << &n2 << endl;
    n1->v.push_back(&n2);

} // life time of n2 ends here

n2驻留在堆栈上。一旦 init 返回,它的生命周期就结束了。因此,对它的引用会导致未定义的行为。尝试 -

n1->v.push_back(new N(2));
于 2013-06-27T20:45:36.933 回答
1

您需要了解范围。n2在函数结束时超出范围(因此超出其内存地址)init

于 2013-06-27T20:46:51.880 回答