容器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);

 得到正确结果:

 

posted @ 2022-06-26 20:52  飞天赤狐  阅读(25)  评论(0)    收藏  举报