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 に答える