删除vector预存迭代器报Vector erase iterator outside range错误如何解决?
问题根因分析
std::vector的底层是连续存储的动态数组,其迭代器失效规则是问题的核心:
当调用push_back()等插入操作时,如果当前容器的预分配容量(capacity())不足以容纳新元素,vector会申请一块更大的连续内存,将原有元素全部拷贝/移动到新内存,然后释放旧内存。这个过程会导致所有之前保存的迭代器、指针、引用全部失效,变成野迭代器。
你提供的代码中,第一次插入元素后vector的初始容量大概率为1,后续循环插入10个元素时必然会触发多次内存重分配,最开始保存的it = vec.begin()早已失效,不属于当前vector的有效迭代器范围,调用erase()时自然会抛出迭代器越界的错误。
正确处理方案
根据业务场景可以选择以下三种常用可行方案:
方案1:提前预分配vector容量,避免插入时内存重分配
如果可以提前预估元素的总数量,调用reserve()方法提前申请足够的内存,插入过程中不会触发重分配,原有迭代器就可以保持有效:
std::vector<foo> vec; vec.reserve(11); // 提前预留至少11个元素的容量,后续插入不会触发重分配 vec.push_back(foo()); std::vector<foo>::iterator it = vec.begin(); for (int i = 0; i < 10; i++) { vec.push_back(foo()); } vec.erase(it); // 此时it仍然有效
注意:预留容量需要大于等于最终的元素总数量,否则插入时依然可能触发扩容导致迭代器失效
方案2:保存元素的下标而非迭代器
下标不受vector内存重分配的影响,插入完成后再通过下标转换为有效迭代器执行删除即可:
std::vector<foo> vec; vec.push_back(foo()); size_t del_index = 0; // 保存要删除元素的下标,而非迭代器 for (int i = 0; i < 10; i++) { vec.push_back(foo()); } vec.erase(vec.begin() + del_index); // 插入完成后通过下标获取当前有效迭代器
方案3:更换为插入不失效旧迭代器的容器
如果业务场景需要频繁插入同时保留旧迭代器,可以选择std::list(链表结构,插入、删除操作不会失效其他元素的迭代器)或者std::deque(首尾插入不会失效指向元素的迭代器)替代std::vector。
内容的提问来源于stack exchange,提问作者Yojhan Steven García Peña
相关产品推荐
相关产品推荐

