STL vector容器需要警惕的一些坑
从迭代器中取值切记需要判断是否为空
例如:
vector<int> vtTest;
vtTest.clear();
if (vtTest.empty()){
return ;
} int *pTest = &vtTest[];
如果没有忘了判断则会出现这样的异常_DEBUG_ERROR("vector subscript out of range");
其实这条异常是Visual C++专有,在g++当中并不会出现,所取得的数值是0。可问题是你怎么区分里面所存的数据本身是0还是vector为空呢?
带有容器的结构体不要使用memset清0
例如以下代码:
struct _Test{
int i;
vector<int> vtTest;
}; _Test test;
memset(&test,,sizeof(test));
test.vtTest.push_back();
test.vtTest.push_back();
test.vtTest.push_back();
其实这部分代码完全可以正常运行,但是如果加上以下代码就一样了
vector<int>::iterator it = test.vtTest.begin();
it++;
问题就出在it++这条语句之上,此时会抛出vector iterator not incrementable
因为在自加的操作中,有这么一条判断
if (this->_Getcont() ==
|| this->_Ptr ==
|| ((_Myvec *)this->_Getcont())->_Mylast <= this->_Ptr)
{ // report error
_DEBUG_ERROR("vector iterator not incrementable");
_SCL_SECURE_OUT_OF_RANGE;
}
在this->_Getcont()函数内部,其实现是这样的;
return (_Myproxy == ? : _Myproxy->_Mycont);
一旦调用上面的memset(&test,0,sizeof(test));之后,vector的_Myproxy数据结构也被清0了,此时_Getcont()函数的返回值就是0,那么程序就会执行到_DEBUG_ERROR("vector iterator not incrementable");经过分析发现,_Myproxy变量是vector用来寻找相邻的数值,而我们的清0操作导致这个链条断裂了,破坏了vector的数据结构从而导致异常。但是g++编译器并没有以上问题,因为VS改写了STL代码。
其实memset清0操作对于结构体或者类都必须慎重,因为很容易破坏自身的数据结构,最典型的就是带有虚函数的类,一旦清0连虚表都给破坏掉了。
vector内存控制
vector每次调用push_back的时候,如果之前内存够用就直接插入,如果不够用了就重新申请一块更大的内存(g++是在原基础上增加一倍长度,VS是增加百分之五十),然后将数据拷贝到新内存当中,释放原内存,再插入新数据。
那么有两个问题,第一,如果能预测到数据量是固定数字,一定要首先预备一块内存,然后插入数据,这样第一避免多次重复申请释放,拷贝等耗资源和时间的无用操作,也可以避免多出一块并不会使用的内存。
其次如果从vector中删除元素,由于vector内存只增不减,当你申请一万个元素空间,删除了9999个,但是其占用仍然是10000个元素空间,如果条件允许,其实可以考虑增加策略来避免内存浪费,因为这些内存只有在析构的时候才会彻底释放掉。如果是指针则必须要手动析构,先遍历逐一delete,然后clear。
由于vector是申请的一块内存,所以如果要从首部删除元素会导致后面的所有元素向前移动一个单位,如果一直这么操作其占用可想而知。。。
STL vector容器需要警惕的一些坑的更多相关文章
- C++ STL vector容器学习
STL(Standard Template Library)标准模板库是C++最重要的组成部分,它提供了一组表示容器.迭代器.函数对象和算法的模板.其中容器是存储类型相同的数据的结构(如vector, ...
- 浅谈C++ STL vector 容器
浅谈C++ STL vector 容器 本篇随笔简单介绍一下\(C++STL\)中\(vector\)容器的使用方法和常见的使用技巧.\(vector\)容器是\(C++STL\)的一种比较基本的容器 ...
- STL - vector容器
1Vector容器简介 vector是将元素置于一个动态数组中加以管理的容器. vector可以随机存取元素(支持索引值直接存取, 用[]操作符或at()方法,这个等下会详讲). vector尾部添加 ...
- STL vector容器 和deque容器
前言 STL是C++的框架,然后vector容器和deque容器又是STL的一部分... 这块的内容都是理解.概念为主,没什么捷径,希望读者能静下来记. 先来讲vector容器(单端动态数组) 1.v ...
- 2.3 C++STL vector容器详解
文章目录 2.3.1 引入 2.3.2 代码实例 2.3.3 运行结果 总结 2.3.1 引入 vector 容器 动态数组 可变数组 vector容器 单口容器(尾部操作效率高) vector动态增 ...
- [C++STL] vector 容器的入门
vector容器的入门 #include<vector> 创建vector容器的几种方式 数据类型可以是结构体,也能是另外一个容器 vector 的初始化: (1) 创建并声明大小 vec ...
- C++STL(二)——vector容器
STL--vector容器 vector对象的概念 vector基本操作 vector对象的初始化.赋值 vector查找.替换(已在上一片 string类 博客总结过了,不再总结) vector添加 ...
- STL vector用法介绍
STL vector用法介绍 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和f ...
- STL vector 用法介绍
介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...
随机推荐
- ionic-CSS:ionic 表单和输入框
ylbtech-ionic-CSS:ionic 表单和输入框 1.返回顶部 1. ionic 表单和输入框 list 类同样可以用于 input 元素.item-input 和 item 类指定了文本 ...
- Unity 之旋转
代码如下: bool RotateDelta(Vector3 direction) { direction.y = ; if (direction == Vector3.zero) return tr ...
- 获取从天气预报接口返回回来的json数据
搬迁到了我的新博客中 ==> http://www.suanliutudousi.com/2017/08/26/%E8%8E%B7%E5%8F%96%E4%BB%8E%E5%A4%A9%E6%B ...
- 大道浮屠诀---mysql5.7.28 for linux安装
环境: redhat6.5 MySQL Community Server 5.7.28 https://dev.mysql.com/downloads/mysql/5.7.html 安装RMP包的具体 ...
- WebService接口测试
- Spring核心接口之InitializingBean
一.InitializingBean接口说明 InitializingBean接口为bean提供了属性初始化后的处理方法,它只包括afterPropertiesSet方法,凡是继承该接口的类,在bea ...
- Java 几种队列区别的简单说明
前言 队列,字面意思就可以明白. 是一种线性的数据暂存与管理工具. 也可以让各种业务功能进行逐个的队列运行. 此篇博客只说明一下Java有几种队列 未阻塞和阻塞队列的区别 未阻塞: 1.未阻塞的队列在 ...
- Windows where
WHERE [/R dir] [/Q] [/F] [/T] pattern... 描述: 显示符合搜索模式的文件位置.在默认情况下,搜索是在当前目录和 PATH 环境变量指定的路径中执行的 ...
- github 拷贝项目到本地
第一步,git config --global --list 验证邮箱 第二步,git config --global user.name "yourname",git confi ...
- SQLServer 中存储过程
SQLServer 中存储过程返回的三种方式( 包括存储过程的创建, 在存储过程中调用, 在VS中调用的方法)存储过程有三种返回: 1. 用return返回数字型数据 2. 用返回参数 ...