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()中的使用.通 ...
随机推荐
- Sigils of Elohim
题目大意 见游戏链接https://store.steampowered.com/app/321480/. 分析 作为一个程序猿,我拒绝用人脑dfs. 代码如下 #include <bits/s ...
- Maven如何发布jar包到Nexus私库
Nexus2可以通过管理界面来上传jar包到私库中,而最新的Nexus3却找不到了上传界面,只能通过以下方式来发布到私库. 发布第三方jar包 这种情况是maven远程仓库没有,本地有的第三方jar包 ...
- C++数据类型之字符串类型&布尔类型&数据的输入
字符串型 **作用**:用于表示一串字符 **两种风格** 1. **C风格字符串**: char 变量名 [ ] = "字符串值" 2.**C++风格字符串**: stri ...
- 城市代码表mysql
只有代码: # ************************************************************ # Sequel Pro SQL dump # Version ...
- iOS开发系列-打印内存地址
打印内存地址 基本数据类型 定义一个基本数据类型,会根据变量类型分配对应的内存空间.比如定义一个int类型的变量a. int a = 10; 内存如下 输入变量a在内存中内存地址 NSLog(@&qu ...
- 【学术篇】SDOI2009 学校食堂
传送门~ 题目大意 先分析\((x\ or\ y)-(x\ and\ y)\), 就是\(x\)和\(y\)中存在的1减去\(x\)和\(y\)中相同的1 *那不就是\(x\ xor\ y\)么←_← ...
- leetcode-63-不同路径②
题目描述: 第一次提交: class Solution: def uniquePathsWithObstacles(self, obstacleGrid) : m = len(obstacleGrid ...
- 【JZOJ6287】扭动的树
description analysis 区间\(DP\),首先按照键值排个序,这样保证树的中序遍历就为原序列 设\(f[0][i][j]\)表示\([i..j]\)区间作为\([unknown..i ...
- 给大家介绍一下linux系统高级命令
输出重定向(mip.0834jl.com) ;覆盖文件内容 回声' 123 ' 测试;覆盖原始内容 回声' 123 ' 测试;原始存在(共存) echo 'ken2 '(www.jl0834.com) ...
- 模拟MySQL命令
staff_table 1,Alex Li,22,13651054608,IT,2013-04-01 2,Jack Wang,30,13304320533,HR,2015-05-03 3,Rain L ...