Aşağıdaki durumda bazı garip davranışlar (clang ve GCC) buldum. nodes
Bir elemanım, bir sınıf örneği olan bir vektörüm var Node
. Daha sonra vektöre nodes[0]
yeni eklenen bir fonksiyon çağırıyorum Node
. Yeni Düğüm eklendiğinde, çağıran nesnenin alanları sıfırlanır! Bununla birlikte, işlev bittiğinde tekrar normale dönüyor gibi görünüyorlar.
Bunun minimal tekrarlanabilir bir örnek olduğuna inanıyorum:
#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;
}
Hangi çıktılar
Before, X = 3
After, X = 0
Finally, X = 3
Yine de X'in süreç tarafından değişmeden kalmasını beklersiniz.
Denediğim diğer şeyler:
Node
İçerisini ekleyen çizgiyi kaldırırsam,set()
her seferinde X = 3 verir.- Yeni bir tane oluşturup
Node
bu (Node p = nodes[0]
) üzerine çağırırsam çıkış 3, 3, 3 olur. - Bir başvuru oluşturur
Node
ve bunu (Node &p = nodes[0]
) olarak çağırırsam , çıkış 3, 0, 0 olur (belki de bunun nedeni, vektör yeniden boyutlandırıldığında referansın kaybolmasıdır?)
Bu herhangi bir nedenle tanımsız bir davranış mı? Neden?
reserve(2)
çağırmadan önce vektör üzerinde çağırmış olsaydınız,set()
bu davranış tanımlanacaktır. Ancak böyle bir işlev yazmakset
, kullanıcınınreserve
tanımlanmamış davranışlardan kaçınmak için çağırmadan önce uygun boyutta olmasını gerektirir , bu yüzden bunu yapmayın.