C++ 结构体中的向量

4
我对使用std::vector有疑问。 如果我有一个结构体,其中包含一个在内存中未定义空间的std::vector对象,如果需要重新分配(std::vector),那么这个结构体是否也会被重新分配?还是只有std::vector会被重新分配?
例如:
struct cluster{
    int a;
    int b;
    struct cluster* parent;
    vector<struct cluster> children;
}

struct cluster obj = {2,1,...};

struct cluster *pobj = &obj;

for(int i = 0; i < 100 ; i ++){
    children.push_back(i); //The capacity will be increased progressly, no?
}

所以,问题是:在 for 循环结束时,pobj==&obj 吗?还是因为子 std::vector 对象的重新分配而重新分配 obj
我希望我解释清楚了我的疑惑。 感谢您的时间。

可能是重复问题:https://dev59.com/aXTYa4cB1Zd3GeqPsDUB - hmjd
3
这个问题没有意义。这是未定义的行为。在声明childs时,cluster是一个不完整的类型,你不能用它来实例化std::vector - juanchopanza
1
正如@juanchopanza所说,声明不完整类型的向量是未定义行为。使用我通常用于自己工作的编译器和选项无法编译(委员会将来可能要求它成为错误)。 - James Kanze
此外:你不需要在每个地方都使用 struct,只需要在定义类时使用即可。(另外,在英语中,“child”的复数形式是“children”,而不是“childs”。英语甚至比 C++ 更不连贯。) - James Kanze
1
你可以看一下 boost::container不完整类型容器。其中有一个 vector 类,允许你进行嵌套操作。 - juanchopanza
显示剩余6条评论
1个回答

7
不,你的obj变量永远不会被重新分配,因为其中的成员发生了变化。向量有其自己指向数据的指针,并在内部处理所有的分配和重新分配。
这样想:通常,本地变量(包括完整结构体和数组)都放在当前函数的堆栈上。编译器通过偏移量从基地址访问这些变量。如果编译器(或系统)突然开始在内存中移动变量,它将大大复杂化变量访问,并且还会影响程序的运行速度和效率。所以本地变量在堆栈上,并保持编译器放置它们的位置不变。在堆上分配的数据(如std::vector内部的数据)可以很容易地移动,因为只需更新指向数据的指针,而且像我之前说的那样,它全部由向量对象在内部处理,所以你不会注意到任何变化。

3
您的解释在一定程度上是不错的,但您真的应该指出,按照目前的写法,他的代码存在未定义行为。(如果使用通常的-D_GLIBCXX_CONCEPT_CHECKS,它在g++中无法编译。) - James Kanze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接