C++ STL vector和map使用注意事项

1,788 阅读2分钟

STL Vector

1、vectorclear 函数和 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方法以后,该元素的位置已经被删除,如果在根据这个旧的位置来获取下一个位置,则会出现异常。