C++ std::vector推回后引用无效

C++ std::vector推回后引用无效,c++,C++,我写了一个例子,它导致了Visual崩溃。我认为关键部分在这里: A a; B b(a); pair p(a, b); res.push_back(p); 我分配一个临时变量,它引用另一个临时变量,并将其移动到向量中。我还注意到,程序似乎没有在GCC中崩溃。我认为问题是,自从我将对象移动到向量中的那一刻起,引用就失效了。我必须用新的吗 在函数make_list中创建的A和B类的实例是本地的,并且仅在函数中有效。对象在堆栈中分配,当程序离开make_列表时,内容可能会被销毁。new可能会有所帮助

我写了一个例子,它导致了Visual崩溃。我认为关键部分在这里:

A a;
B b(a);
pair p(a, b);
res.push_back(p);
我分配一个临时变量,它引用另一个临时变量,并将其移动到向量中。我还注意到,程序似乎没有在GCC中崩溃。我认为问题是,自从我将对象移动到向量中的那一刻起,引用就失效了。我必须用新的吗


在函数make_list中创建的A和B类的实例是本地的,并且仅在函数中有效。对象在堆栈中分配,当程序离开make_列表时,内容可能会被销毁。new可能会有所帮助,因为对象是在堆中分配的,并且在释放分配的内存之前都会在堆中

#include <iostream>
#include <string>
#include <vector>
#include <math.h>

class Materials {
public:
    Materials() = default;
};

class A {
private:
    std::vector<Materials> _storage;

public:
    void setStorage(const std::vector<Materials> &val) {
        _storage = val;
    }
};

class B {
private:
    A _a;

public:
    B(A &foo) : _a(foo) {}

    void run() {
        std::vector<Materials> val;
        for (int i = 0; i < 1000; i++) {
            val.push_back(Materials{});
        }

        _a.setStorage(val);
    }
};

struct pair1 {
    pair1(const A &a, const B &b)
        : _a(a)
        , _b(b)
    {
    }
    //pair1(const pair1& p) :pair1(p._a, p._b) {}

    A _a;
    B _b;
};

std::vector<pair1> make_list() {
    std::vector<pair1> res;
    for (int i = 0; i < 10; i++) {
        A a;
        B b(a);
        pair1 p(a, b);
        res.push_back(p);
    }
    return res;
}

int main()
{
    std::vector<pair1> list = make_list();
    B &ref = list.at(1)._b;
    ref.run();
}
一,。您不使用移动语义

您可以更改材质,因为它看起来像函数材质{}看起来像构造函数

问题是A&_A变为A _A

可能命名为struct,因为在标准库中是pair,并且您定义了太多pair 您应该使用list.at1 no list[1],因为第一个解决方案提供了更多的异常等信息。
您是否调试以找到导致崩溃的语句?为什么不复制或移动到对象中,而不是存储一个注定失败的引用?我认为这是一个X/Y问题。你想做什么,为什么你认为使用一个参考会是一个好主意,特别是对一个临时的?还有,我不知道你为什么要重新设计这对。你是对的,我应该让最小值更容易一点。@dgrat是的,请。否则很容易错过该循环:P@CinCout:是的,他们做了,他们的分析是正确的。现在找到调试器无法执行的解决方案。最终的解决方案是重新设计,因此强调d的后续问题至关重要。简言之,这里有很多不需要的副本。没有人试图访问这些本地人。见2是完全错误的;这只是调用构造函数的两种不同方式。此外,在第5条上不同意:如果不期望可以给出无效索引(例如,来自任意用户输入),则运算符[]可以很好地减少开销。第二节批评家的意思是什么,也许最重要的改变是?有了构造函数,我想到了一些不同的东西,所以我改进了,5。在编写代码时更安全。我明白你关于5的观点。就我个人而言,我更喜欢使用一个带有调试模式选项的库来检查操作符[]中的索引,然后在发布版本中将其关闭-这避免了在不需要的情况下将slow.at放入发布的代码中,或者用户必须进行大量可能容易出错的查找和替换。
#include <iostream>
#include <string>
#include <vector>
#include <math.h>

class Materials {
public:
    Materials() = default;
};

class A {
private:
    std::vector<Materials> _storage;

public:
    void setStorage(const std::vector<Materials> &val) {
        _storage = val;
    }
};

class B {
private:
    A _a;

public:
    B(A &foo) : _a(foo) {}

    void run() {
        std::vector<Materials> val;
        for (int i = 0; i < 1000; i++) {
            val.push_back(Materials{});
        }

        _a.setStorage(val);
    }
};

struct pair1 {
    pair1(const A &a, const B &b)
        : _a(a)
        , _b(b)
    {
    }
    //pair1(const pair1& p) :pair1(p._a, p._b) {}

    A _a;
    B _b;
};

std::vector<pair1> make_list() {
    std::vector<pair1> res;
    for (int i = 0; i < 10; i++) {
        A a;
        B b(a);
        pair1 p(a, b);
        res.push_back(p);
    }
    return res;
}

int main()
{
    std::vector<pair1> list = make_list();
    B &ref = list.at(1)._b;
    ref.run();
}