Saya telah menemukan beberapa perilaku yang sangat aneh (pada dentang dan GCC) dalam situasi berikut. Saya punya vektor,, nodesdengan satu elemen, turunan dari kelas Node. Saya kemudian memanggil fungsi nodes[0]yang menambahkan baru Nodeke vektor. Ketika Node baru ditambahkan, bidang objek panggilan direset! Namun, mereka tampaknya kembali normal lagi setelah fungsi selesai.
Saya percaya ini adalah contoh minimal yang dapat direproduksi:
#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;
}
Output yang mana
Before, X = 3
After, X = 0
Finally, X = 3
Meskipun Anda akan mengharapkan X tetap tidak berubah oleh proses.
Hal lain yang saya coba:
- Jika saya menghapus baris yang menambahkan bagian
Nodedalamset(), maka itu menghasilkan X = 3 setiap kali. - Jika saya membuat yang baru
Nodedan menyebutnya (Node p = nodes[0]) maka hasilnya adalah 3, 3, 3 - Jika saya membuat referensi
Nodedan menyebutnya pada itu (Node &p = nodes[0]) maka hasilnya adalah 3, 0, 0 (mungkin yang ini adalah karena referensi tersebut hilang ketika vektor diubah ukurannya?)
Apakah ini perilaku yang tidak terdefinisi untuk beberapa alasan? Mengapa?
reserve(2)vektor sebelum memanggilset()ini akan didefinisikan perilaku. Tapi menulis fungsi sepertisetitu mengharuskan pengguna untukreserveukuran yang cukup sebelum memanggilnya untuk menghindari perilaku yang tidak jelas adalah desain yang buruk, jadi jangan lakukan itu.