学习C++,vector是绕不过的,之所以用vector,根本原因,在于我自己搞不定“如何创建一个动态数组”这个常见的问题,于是我只好引入了vector,不好我觉得还是有必要探讨一下vector在内存管理方面的一些情况。
问题1:vector的push_back添加数据,究竟是内存拷贝还是指针指向?
先思考,如果是内存拷贝的话,那么对于程序员来说,是绝对安全的,比如我申请了一个内存,这个内存只用来存放android这个字符串,然后我把这个字符串通过push_back赋值给vector变量,vector把这个内存拷贝了一份,拷贝到另外的内存地址上去,那么对于我来说,绝对安全了,哪怕我把原来android字符串变成其他的,或者销毁掉,也无所谓,因为vector已经复制了一份。但是问题在于,vector这样做很占空间。那么vecotr是怎么做的呢?
看实际情况,来代码
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//先声明一个vector变量
vector<char*> f;
//新建一个s字符串,指向50个字的空间,空间里只存放android这个字符串
char* s = new char[50] {"android"};
//把这个字符串存入vector
f.push_back(s);
//毫无疑问,打印出来android
printf("%s\n", f[0]);
//先把s指针清空,然后赋值meizu
memset(s, 0, strlen(s));
memcpy_s(s, 5, "meizu", 5);
//再打印一下,猜猜看,会打印出来什么?结果是,打印出来meizu
printf("%s\n", f[0]);
}
根据代码的结果,毫无疑问,
vector的赋值操作,仅仅是存了一个指针,指向了指针s。
所以,我得到结论,千万不能随意delete[] s,否则数据会丢失。
问题2:vector两个变量之间的赋值,比如V1=V2,是内存拷贝还是指针指向?
先思考,根据问题一,鉴于vector对内存占用比较谨慎的作风,我们判断这里仅仅是指针指向,加入V1清空的话,V2里面的数据也会没有。
那么,实际情况是这样的吗?看代码,在上面的代码的基础上,加了几行
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//先声明一个vector变量
vector<char*> f;
//新建一个s字符串,指向50个字的空间,空间里只存放android这个字符串
char* s = new char[50] {"android"};
//把这个字符串存入vector
f.push_back(s);
//毫无疑问,打印出来android
printf("%s\n", f[0]);
//先把s指针清空,然后赋值meizu
memset(s, 0, strlen(s));
memcpy_s(s, 5, "meizu", 5);
//再打印一下,打印出来meizu
printf("%s\n", f[0]);
//再声明一个vector变量
vector<char*> f2;
//f赋值给f2
f2 = f;
vector<char*> nullChar;
//释放f做占用的内存
f.swap(vector<char*>());
//现在打印出来f2的第一个值,猜猜看,能打印出来什么?纳尼?打印出来meizu了?!!!
printf("%s\n", f2.at(0));
//我不信,我再看一遍f,看看它是否被清空了~~~~真的被清空了,打印出来0
printf("%d\n", f.size());
system("pause");
}
根据上面的结果,我们得到结论,
我们猜错了,V2=V1是内存拷贝
问题3:vector的clear和swap有啥区别?
这个不好写代码验证,但是根据STL的说明,swap比clear更彻底一些,能够保证占用的内存归还给了操作系统。
结论:用swap好一些,至于clear么,大家都说会引起内存泄漏,因为clear并没有真正释放空间
个人结论:vector对内存的管理比较严格
思路扩展:玩C++,要注意内存管理。
1.new是很爽,爽完不要忘记delete,不然泄露了就够喝一壶的了。
2.but,也不要看着new就delete,不然vector咋办,就像问题1,vector的android变成了meizu
3.释放内存,释放内存!!!要看看是否彻底的释放了内存,比如用swap就彻底一些,clear就不彻底,还会引发内存泄漏