【问题标题】:Issue when implementing a Node class实现 Node 类时的问题
【发布时间】:2013-06-28 05:00:37
【问题描述】:

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

#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好像不存在了。

感谢您的帮助。

【问题讨论】:

  • 运行程序时会发生什么?输出与您的预期有何不同?

标签: c++ pointers constructor


【解决方案1】:

因为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 运算符释放它们的内存(例如,在N 的析构函数中):

~N() {
  for (int i = 0; i < v.size(); ++i) {
    delete v[i];
  }
  v.clear();
}

【讨论】:

  • 不要忘记使用new创建的任何变量都必须使用delete删除,否则你的程序会出现内存泄漏。
  • @DavidFreitag:谢谢你的提醒。我已将其包含在我的答案中。
【解决方案2】:

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

【讨论】:

    【解决方案3】:
    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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-08
      • 2019-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 1970-01-01
      相关资源
      最近更新 更多