在std :: vector push_back之后引用无效

时间:2017-07-04 11:28:16

标签: c++

我写了一个用Visual引导崩溃的例子。我认为关键部分在这里:

A a;
B b(a);
pair p(a, b);
res.push_back(p);

我指定一个临时的,它引用另一个临时的并将其移动到一个向量中。我也注意到该程序似乎没有与GCC崩溃。我认为问题是,从我将对象移动到向量中的那一刻起,引用就失效了。我必须使用new吗?

// ConsoleApplication1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


// Example program
#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 pair {
  pair(const A &a, const B &b)
    : _a(a)
    , _b(b)
  {
  }

  A _a;
  B _b;
};

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

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

2 个答案:

答案 0 :(得分:0)

#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();
}

1。你没有使用移动语义

  1. 您可以更改Materials(),因为看起来像一个函数Materials{}看起来像一个构造函数

  2. 问题是A &_a更改为A _a

  3. 可能是名称结构,因为在标准库中pair,您定义pair
  4. 您应该使用list.at(1)list[1],因为第一个解决方案会提供更多信息(例外等)。

答案 1 :(得分:-3)

在函数make_list中创建的A和B类的实例是本地的,仅在函数内有效。对象以堆栈形式分配,当程序离开make_list时,内容可能会被销毁。 &#34;新&#34;可以提供帮助,因为对象在堆中分配并且将一直存在,直到释放分配的内存。