std::vector 中的 erase() 操作
迭代器失效情况
在 std::vector 中,调用 erase() 会移除一个或多个元素,并会导致某些迭代器失效。具体的迭代器失效情况如下:
- 单个元素的erase:如果调用 erase 移除单个元素,指向被移除元素及其之后元素的所有迭代器都会失效。指向被移除元素之前的迭代器仍然有效。
- 范围erase:如果调用 erase 移除一个范围内的元素,同样会使得指向被移除范围内及其之后元素的所有迭代器失效。指向被移除范围之前的迭代器仍然有效。
例如:
std::vector vec = {1, 2, 3, 4, 5};
auto it = vec.begin() + 2; // 指向元素 3
vec.erase(it); // 移除元素 3,it 和其之后的迭代器失效
erase 是否释放内存
调用 erase 移除元素时,std::vector 不会释放其容量内存。它只是调整了内部的大小信息(size),并将元素从逻辑上移除。内存管理如下:
- 析构对象:erase 会调用被移除元素的析构函数来销毁这些对象。
- 调整大小:erase 会调整内部的 size 以反映新的元素数量。
- 内存未释放:erase 不会调整 vector 的 capacity,也就是说,它不会释放已经分配的内存。这样做的目的是为了避免频繁的内存分配和释放,以提高性能。
如果需要在 erase 之后释放未使用的内存,可以调用 shrink_to_fit() 方法或通过交换技术来实现。
std::vector vec = {1, 2, 3, 4, 5};
vec.erase(vec.begin() + 1, vec.begin() + 3); // 移除元素 2 和 3
vec.shrink_to_fit(); // 请求释放未使用的内存
或者
std::vector vec = {1, 2, 3, 4, 5};
vec.erase(vec.begin() + 1, vec.begin() + 3); // 移除元素 2 和 3
std::vector(vec).swap(vec); // 清除多余的容量内存
实现细节
erase 实现的简化版本
以下是一个简化版本的 erase 实现,以说明其工作原理:
template
class SimpleVector {
private:
T* data;
size_t size;
size_t capacity;
public:
// 构造函数和析构函数省略
void erase(size_t pos) {
if (pos >= size) return;
// 调用析构函数销毁被移除的元素
data[pos].~T();
// 移动后续元素
for (size_t i = pos; i < size - 1; ++i) {
data[i] = std::move(data[i + 1]);
}
// 调整大小
--size;
}
// 其他成员函数省略
};
总结
- 调用 erase 后,指向被移除元素及其后的迭代器失效。
- erase 不会释放 vector 的内存容量,只是调整大小并销毁被移除的元素。
- 如果需要释放未使用的内存,可使用 shrink_to_fit() 或交换技术。