Aşağıdaki durumda bazı garip davranışlar (clang ve GCC) buldum. nodesBir 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
Nodebu (Node p = nodes[0]) üzerine çağırırsam çıkış 3, 3, 3 olur. - Bir başvuru oluşturur
Nodeve 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ınreservetanımlanmamış davranışlardan kaçınmak için çağırmadan önce uygun boyutta olmasını gerektirir , bu yüzden bunu yapmayın.