容器renew导致的指针失效
问题场景:
以vector为例,有时候我们会把原始数据列表作为vector数组,同时把需要排序或其他处理的数组使用指向原始vector的迭代器数组
示例代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Person
{
public:
Person()
{
age = 0;
}
string name;
int age;
};
typedef vector<Person>::iterator PersonPtr;
int main(int argc, char* argv[])
{
vector<Person> personArray;
Person p1;
p1.age = 10;
p1.name = "小明";
Person p2;
p2.age = 30;
p2.name = "王亮";
Person p3;
p3.age = 12;
p3.name = "小丽";
Person p4;
p4.age = 9;
p4.name = "小华";
personArray.push_back(p1);
personArray.push_back(p2);
personArray.push_back(p3);
personArray.push_back(p4);
vector<PersonPtr> personItArray;
for(auto it = personArray.begin(); it != personArray.end(); ++it)
{
personItArray.push_back(it);
}
std::stable_sort(personItArray.begin(), personItArray.end(), [](PersonPtr a, PersonPtr b){return a->age < b->age;});
//在后面处理中又插入了一个新的person
Person p5;
p5.name = "李雷";
p5.age = 15;
personArray.push_back(p5);
cout << personArray.capacity() << endl;
for(auto personPtr : personItArray)
{
cout << "name:" << personPtr->name << ", age:" << personPtr->age << endl;
}
return 0;
}
运行结果, 程序core掉:
问题原因:
4个元素的时候,vector内部处于需要renew的边界,当再插入1个的时候,出发了renew,之前的迭代器数组中插入的迭代器指向了错误的地址
解决方式:
尽量避免使用非临时场景的vector迭代器、指针,如果必须要使用,确保vector不会再次renew而导致指向错误内存
可以根据需要提前reserve一个足够的空间, 中前面问题代码中增加 reserve:
Person p4;
p4.age = 9;
p4.name = "小华";
personArray.reserve(20); //提前reserve足够空间
personArray.push_back(p1);
得到正确结果: