【发布时间】:2020-06-15 02:59:44
【问题描述】:
在以下情况下,我发现了一些非常奇怪的行为(在 clang 和 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 在该过程中保持不变。
我尝试过的其他事情:
- 如果我删除在
set()中添加Node的行,那么它每次都会输出X = 3。 - 如果我创建一个新的
Node并在其上调用它 (Node p = nodes[0]),则输出为 3、3、3 - 如果我创建一个引用
Node并在其上调用它 (Node &p = nodes[0]),则输出为 3、0、0(也许这是因为当向量调整大小时引用丢失了?)
这是出于某种原因未定义的行为吗?为什么?
【问题讨论】:
-
见en.cppreference.com/w/cpp/container/vector/push_back。如果您在调用
set()之前在向量上调用reserve(2),这将被定义为行为。但是写一个像set这样的函数,要求用户在调用它之前适当地reserve足够的大小以避免未定义的行为是不好的设计,所以不要这样做。
标签: c++ vector stdvector undefined-behavior push-back