C++ 为什么指向向量第一个元素的指针丢失了? #包括 #包括 //#包括 结构点{ 点(整数x,整数y){ x=x; y=_y; } int x; int-y; 点*父项; }; int main(){ 起点(3,4); std::向量点; 点。向后推(开始); std::cout

C++ 为什么指向向量第一个元素的指针丢失了? #包括 #包括 //#包括 结构点{ 点(整数x,整数y){ x=x; y=_y; } int x; int-y; 点*父项; }; int main(){ 起点(3,4); std::向量点; 点。向后推(开始); std::cout,c++,c++11,pointers,stdvector,C++,C++11,Pointers,Stdvector,std::vector具有容量。如果您添加的元素超出了该向量的当前容量,则vector可能会决定分配一个更大的块,移动现有元素,然后添加新元素。这在您的情况下也一定发生过 您可以使用保留增加现有向量的容量。这还不会添加额外的元素;它只是准备向量。虽然MSalters正确解释了问题的原因,以及此特定情况下可能的解决方案,但一般做法有点不同。因为向量可能是重新分配的在任何时候,存储指向其元素的指针通常都不是一个好主意。 您可以使用索引,而不是重新分配,这将是有效的;或者您可以考虑使用不同的数据结构,

std::vector
具有
容量
。如果您添加的元素超出了该向量的当前容量,则vector可能会决定分配一个更大的块,移动现有元素,然后添加新元素。这在您的情况下也一定发生过


您可以使用
保留
增加现有向量的容量。这还不会添加额外的元素;它只是准备向量。

虽然MSalters正确解释了问题的原因,以及此特定情况下可能的解决方案,但一般做法有点不同。因为
向量
可能是重新分配的在任何时候,存储指向其元素的指针通常都不是一个好主意。 您可以使用索引,而不是重新分配,这将是有效的;或者您可以考虑使用不同的数据结构,如<代码> STD::List。
std::list
的元素在其整个生命周期中都保持在相同的位置。

一旦执行了
点操作,则向后推(一);
std::vector
允许在保存所有数据的位置重新分配整个数组,因此这意味着如果您以前存储了指针,例如:
&points.back()
,它可能不再有效。注意:如果需要扩展代码,此问题的一个更安全的解决方案将扩展为
vector
A
std::vector
,并使
Point
parent
成员也成为
std::shared\u ptr
(假设它是a;如果它可以有周期,则需要
std::weak_ptr
,并且管理变得更加困难)。这避免了
和存储它们的
向量
之间的紧密耦合(其中
父项
仅在有效全局
向量
的上下文中才有意义)。明智地使用
std::make_shared
(这既安全又允许直接
std::shared_ptr
无法实现的性能优化)注意:如果您知道
向量的最终大小或最大大小,适当的
reserve
调用可以确保有效指针保持有效,只要所讨论的元素没有被移动/替换。我不会说存储指向
v的指针总是一个坏主意ector
元素,只是如果你不能
保留
/
向量大小调整到一个永远不会超过的大小,这是一个坏主意。@ShadowRanger你是对的。但是如果你这样做,你必须100%确定将来没有人想在
向量中添加更多元素,比如说在年后的5年或10年内当产品需求可能演变成完全不同的东西时。@ July:好的设计是将向量封装在一个具有良好定义的外部接口的类中。如果产品需求发展,那么就可以考虑该类是否可以按需使用,需要更新,或者需要重写。:它可能会为额外元素的原始实例结构消耗内存(当然是虚拟地址空间,占用的实际RAM数量与实现密切相关),因此对于OP中的
std::vector
,调用
reserve
通常会保留12-16字节的内存(取决于指针宽度)乘以保留的大小。它不必初始化内存,对于实例在堆上间接存储昂贵属性的类,不会立即支付该成本,但它必须保留原始内部数组。
#include <iostream>
#include <vector>
//#include <string>

struct Point {
    Point(int _x, int _y) {
        x = _x;
        y = _y;
    }

    int x;
    int y;
    Point *parent;
};

int main() {

    Point start(3, 4);
    std::vector<Point> points; 
    points.push_back(start);
    std::cout << points.back().x << "," << points.back().y << "\n";

    Point one(4, 5);
    one.parent = &points.at(0);
    //std::cout <<  "testing: " << one.parent->x << "," << one.parent->y << "\n";
    points.push_back(one);
    std::cout << "One: " << points[1].x << "," << points[1].y << "\n";
    std::cout << "One's parents: " << points[1].parent->x << "," << points[1].parent->y << "\n";

    Point two(10, 3);
    two.parent = &points.back();
    points.push_back(two);
    std::cout << "Two: " << points[2].x << "," << points[2].y << "\n";
    std::cout << "Two's parent: " << points[2].parent->x << "," << points[2].parent->y << "\n";

    Point three(12, 7);
    three.parent = &points[1];
    points.push_back(three);
    std::cout << "Three: " << points[3].x << "," << points[3].y << "\n";
    std::cout << "Three's parents: " << points[3].parent->x << "," << points[3].parent->y << "\n";


    return 1;
}