STL Vector
1、vector
的 clear
函数和 erase
函数并不会对内存进行回收,会导致内存泄漏。需要回收内存,最简单的方法是使用 swap
函数和临时变量交换。
#include <iostream>
#include <vector>
#include <windows.h>
#include <psapi.h>
#pragma comment(lib,"psapi.lib")
int ShowMemoryInfo(void) {
HANDLE handle = GetCurrentProcess();
PROCESS_MEMORY_COUNTERS pmc;
GetProcessMemoryInfo(handle, &pmc, sizeof(pmc));
return pmc.WorkingSetSize / 1000;
}
int main(int argc, char *argv[]) {
std::vector<int> v;
std::cout << "start memory: " << ShowMemoryInfo() << "KB" << std::endl;
for (int i = 0; i < 10000000; i++) {
v.push_back(i);
}
std::cout << "after push: " << ShowMemoryInfo() << "KB" << ",size=" << v.size() << ",capacity=" << v.capacity() << std::endl;
v.clear();
std::cout << "after clear: " << ShowMemoryInfo() << "KB" << ",size=" << v.size() << ",capacity=" << v.capacity() << std::endl;
{
std::vector<int> tmp;
tmp.swap(v);
}
std::cout << "after swap: " << ShowMemoryInfo() << "KB" << ",size=" << v.size() << ",capacity=" << v.capacity() << std::endl;
return 0;
}
output:
start memory: 4100KB
after push: 52506KB,size=10000000,capacity=11958657
after clear: 52514KB,size=0,capacity=11958657
after swap: 4579KB,size=0,capacity=0
2、因为 vector
使用一个数组作为它的底层存储,移除向量除尾端以外位置的元素,会导致容器在操作之后将所有元素重新定位到它们的新位置。与其他类型的序列容器(如list或forward_list)相比,vector 的 erase 通常是一个低效的操作。
循环删除vector/set/map中元素
- 正确方法1:
std::vector<int> v;
int del = 1;
for (auto it = v.begin(); it != v.end(); ) {
if (*it == del) {
it = v.erase(it); // erase函数返回删除元素后面的一个元素的迭代器
} else {
it++;
}
}
- 正确方法2:
std::vector<int> v;
int del = 1;
for (auto it = v.begin(); it != v.end(); ) {
if (*it == del) {
v.erase(it++);
} else {
it++;
}
}
1、通过erase方法的返回值来获取下一个元素的位置
2、在调用erase方法之前先使用 “++”来获取下一个元素的位置
- 错误方法
std::vector<int> v;
int del = 1;
for (auto it = v.begin(); it != v.end(); it++) {
if (*it == del) {
v.erase(it);
}
}
在调用erase方法之后使用“++”来获取下一个元素的位置,由于在调用erase方法以后,该元素的位置已经被删除,如果在根据这个旧的位置来获取下一个位置,则会出现异常。