Eu encontrei um comportamento muito estranho (no clang e no GCC) na seguinte situação. Eu tenho um vetor, nodes
com um elemento, uma instância de classe Node
. Então, chamo uma função nodes[0]
que adiciona um novo Node
ao vetor. Quando o novo Nó é adicionado, os campos do objeto de chamada são redefinidos! No entanto, eles parecem voltar ao normal novamente quando a função é concluída.
Eu acredito que este é um exemplo reprodutível mínimo:
#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;
}
Quais saídas
Before, X = 3
After, X = 0
Finally, X = 3
Embora você espere que o X permaneça inalterado pelo processo.
Outras coisas que eu tentei:
- Se eu remover a linha que adiciona um
Node
interiorset()
, ela gera X = 3 sempre. - Se eu criar um novo
Node
e chamar assim (Node p = nodes[0]
), a saída será 3, 3, 3 - Se eu criar uma referência
Node
e chamar isso de (Node &p = nodes[0]
), então a saída será 3, 0, 0 (talvez essa seja porque a referência é perdida quando o vetor é redimensionado?)
Esse comportamento é indefinido por algum motivo? Por quê?
reserve(2)
o vetor antes de chamarset()
isso, seria um comportamento definido. Mas escrever uma função comoset
essa requer que o usuário tenhareserve
tamanho suficiente antes de chamá-la, a fim de evitar um comportamento indefinido é um design ruim, portanto, não faça isso.