【003】erase()删除vector容器中指针变量,会同时释放该指针变量的内存吗?
文章目录1. 概述2. 验证3. 源码分析erase() 4. 总结1. 概述若使用STL中的vector容器,用来存储指针变量(即char*),那么当我们使用erase()函数去删除该容器中的指针变量元素时候,该指针变量申请的内存空间地址会不会被erase()函数在底层给释放掉?这个问题是比较重要的。如果erase()函数不会去释放掉指针变量对应的内存空间,那么在我们没有手动去释放vector容
1. 概述
使用STL中的vector容器,用来存储指针变量(即char*
),那么当我们使用erase()
函数去删除该容器中的指针变量元素时候,该指针变量申请的内存空间地址会不会被erase()
函数在底层给释放掉?
这个问题是比较重要的。如果erase()
函数不会去释放掉指针变量对应的内存空间,那么在我们没有手动去释放vector
容器中的指针变量时候,会导致内存泄露,这是个十分严重的问题。
2. 验证
为了验证这个问题,我们写一个小demo来亲自测试看看结果现象。
我们定义两个指针变量pName
和pAddr
。然后分别申请相应大小(p1
、p2
)的内存空间;若内存申请成功,则分别将p1
、p2
中的字符串拷贝到pName
、pAddr
中。接着讲pName
和pAddr
这两个指针变量存储到vector容器(vPointers
)中。然后打印vPointers
容器中的所有元素值。
在删除vPointers
容器所有元素之前,使用两个临时指针变量p3
、p4
分别指向pName
、pAddr
所指向的内存空间。之后删除该vector容器(vPointers
)中的所有元素(即pName
和pAddr
),
接着再次打印临时指针变量p3
、p4
所指向的内存空间地址中的内容,发现依然有数据。内存空间并没有被erase()
函数释放,因此,这表明erase()
函数底层不会对用户的指针变量做任何操作,它仅仅负责删除vector容器中的元素罢了。
示例代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <vector>
#include <list>
#include <iostream>
using namespace std;
int main()
{
vector<char*> vPointers;
char *p1 = "lixiaogang5", *p2 = "guizhousheng";
//malloc不会对申请的内存空间清零.
char *pName = (char*)calloc(1, strlen(p1) + 1);
strncpy(pName, p1, strlen(p1));
char *pAddr = (char*)malloc(strlen(p2) + 1);
assert(pAddr);
strncpy(pAddr, p2, strlen(p2));
vPointers.push_back(pName);
vPointers.push_back(pAddr);
cout << "===============================================" << endl;
cout<<"vPointers.size(): "<<vPointers.size()<<endl;
for(auto &v : vPointers)
{
cout << v <<endl;
}
cout << "===============================================" << endl;
//address
printf("pName: %p, pAddr: %p\n", &(*pName), &(*pAddr));
char *p3 = pName, *p4 = pAddr;
printf("p3: %p, p4: %p\n", &(*p3), &(*p4));
cout << "===============================================" << endl;
auto it = vPointers.begin();
for(; it != vPointers.end(); )
{
it = vPointers.erase(it);
}
cout << "vPointers.size(): "<<vPointers.size()<<endl;
cout << "===============================================" << endl;
cout << "p3: "<< p3 << endl;
cout << "p4: "<< p4 << endl;
cout << "===============================================" << endl;
if(p3) free(p3), p3 = NULL;
if(p4) free(p4), p4 = NULL;
return 0;
}
打印结果如下图所示:
3. 源码分析erase()
在stl_vector.h
文件中,实现了vector
容器的声明,其中也给出了erase()
的函数原型。
erase()
函数支持删除迭代器指定的一个元素、或是两个指定迭代器(__first
、__last
)区间的所有元素。
#if __cplusplus >= 201103L
erase(const_iterator __position)
{ return _M_erase(begin() + (__position - cbegin())); }
#else
erase(iterator __position)
{ return _M_erase(__position); }
#endif
iterator
#if __cplusplus >= 201103L
erase(const_iterator __first, const_iterator __last)
{
const auto __beg = begin();
const auto __cbeg = cbegin();
return _M_erase(__beg + (__first - __cbeg), __beg + (__last - __cbeg));
}
#else
erase(iterator __first, iterator __last)
{ return _M_erase(__first, __last); }
#endif
从该源码中可看到erase()
函数仅是删除指定迭代器对应的数据元素,而不会去调用类似free()
之类的函数。
同样,clear()
函数亦如此。
4. 总结
vector容器中的erase()
函数仅删除迭代器所指定的数据元素,不会对用户本身的数据所过多的干涉。如果待存储vector容器中的元素是指针变量,需要用户自己去管理指针变量对应的内存空间地址。同理,clear()
函数也一样。
更多推荐
所有评论(0)