Qq0:
私は、次のような状況で(打ち鳴らすとGCCの)いくつかの非常に奇妙な行動を発見しました。私は、ベクトルを持っているnodes
一つの要素、クラスのインスタンスで、Node
。私は、上の関数を呼び出しnodes[0]
、新規に追加し、そのNode
ベクトルにします。新しいノードが追加されると、呼び出し元のオブジェクトのフィールドがリセットされ!しかし、彼らは関数が終了した後、再び正常に戻るように見えます。
私は、これは、最小限の再現性の例であると考えています。
#include <iostream>
#include <vector>
using namespace std;
struct Node;
vector<Node> nodes;
struct Node{
int X;
void set(){
X = 3;
cout << "Before, X = " << X << endl;
nodes.push_back(Node());
cout << "After, X = " << X << endl;
}
};
int main() {
nodes = vector<Node>();
nodes.push_back(Node());
nodes[0].set();
cout << "Finally, X = " << nodes[0].X << endl;
}
どの出力
Before, X = 3
After, X = 0
Finally, X = 3
あなたが期待するもののXは、プロセスによって変更されないままにします。
私が試してみました他のもの:
- 私は追加の行削除した場合
Node
の内部をset()
、それがX = 3たびに出力します。 - 私は新しいを作成した場合
Node
と、(その上でそれを呼び出すNode p = nodes[0]
)、出力は3、3、3です - 私は、参照を作成する場合
Node
と、(その上でそれを呼び出すNode &p = nodes[0]
)が出力されている3、0、0(参照はとき、ベクトルサイズ変更が失われているので、おそらくこの1つはあります?)
何らかの理由で、この未定義の動作ですか?どうして?
NathanOliver:
あなたのコードは未定義の動作を持っています。に
void set(){
X = 3;
cout << "Before, X = " << X << endl;
nodes.push_back(Node());
cout << "After, X = " << X << endl;
}
アクセスがX
本当にあるthis->X
とthis
ベクトルのメンバーへのポインタです。あなたが行うときnodes.push_back(Node());
、あなたはベクトルとそのプロセスの再割り当て、に新しい要素を追加し、すべてのイテレータ、ポインタと参照を無効にベクトルの要素に。その意味
cout << "After, X = " << X << endl;
使用されthis
なくなった有効であることを。