存储指针的vector输出异常

我想把一个vector的所有元素的地址存在另外一个vector中,但是调用这个存有地址时候会输出错误,为什么呢?

#include <iostream>
#include <vector>

struct a
{
    int id;
};
int main() 
{
  a tmp_a;
  std::vector<a> b;
  std::vector<a*> ptr_b;
    
  for(size_t i=0; i<5; i++)
  {
    tmp_a.id = i;
    b.push_back(tmp_a);
    ptr_b.push_back(&b.at(i));
    std::cout<< ptr_b[i]->id <<std::endl;
  }
  for(size_t j=0; j<5; j++)
  {
    std::cout<< ptr_b[j]->id <<std::endl;
  }
  return 0;
}

输出结果:

0
1
2
3
4
34889408
0
34811920
0
4

这设计到vector内部的实现原理,关于内存管理的部分。它实际上内部有一段动态分配的连续内存,相当于数组,来存放新加入的元素,它会在内部存放一份元素的副本,对于元素是类或者结构类型来说会调用它们的复制构造函数来创建新的对象。当内部数组的大小不足的时候,它会再重新分配一段足够大的内存,用复制构造函数来把旧内存里面的对象复制到新内存里,再释放掉旧内存。你最后调用的for循环,里面用到的内存有的已经被释放掉了,但内存地址还保存在ptr_b里面。你可以这么改,来观察整个过程

struct a
{
	int id;
	a(){
		cout << "a()" << endl;

	}
	a(const a& t){
		id = t.id;
		cout << "a(const a&)" << endl;
	}

	~a(){
		cout << "~a()" << endl;
	}
};

 

这种写法可以:

#include <iostream>
#include <vector>

struct a
{
    int id;
};
int main()
{
    a tmp_a;
    std::vector<a> b;
    std::vector<a*> ptr_b;

    for(size_t i=0; i<5; i++)
    {
        tmp_a.id = i;
        b.push_back(tmp_a);
        //ptr_b.push_back(&b.at(i));
        //std::cout<< ptr_b[i]->id <<std::endl;
    }
    for(size_t i=0; i<b.size(); i++){
        ptr_b.push_back(&b.at(i));
        std::cout<< ptr_b[i]->id <<std::endl;
    }
    for(size_t j=0; j<5; j++)
    {
        std::cout<< ptr_b[j]->id <<std::endl;
    }
    return 0;
}

 

或者 用C++11 的auto方式的引用遍历 可以遍历的同时做修改