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()中的使用.通 ...
随机推荐
- jvm-多线程
多线程的目的 为什么要使用多线程?可以简单的分两个方面来说: 在多个cpu核心下,多线程的好处是显而易见的,不然多个cpu核心只跑一个线程其他的核心就都浪费了: 即便不考虑多核心,在单核下,多线程也是 ...
- c++-字符串和时间操作
C++ 字符串 C++ 提供了以下两种类型的字符串表示形式: C 风格字符串 C++ 引入的 string 类类型 C 风格字符串 C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持.字符 ...
- class5_Radiobutton 选择按钮(选项选择)
最终的运行效果图(程序见序号4) #!/usr/bin/env python# -*- coding:utf-8 -*-# -------------------------------------- ...
- mysql安装总结
#mysql安装# 安装工具:yum -y install gcc-c++ ncurses cmake make ncurses-devel # 拷贝配置文件到指定目录:rm -rf /etc/my. ...
- moment 获取当前月日历
获取当前月日历 <template> <div id="calendar"> <div class="top">{{date ...
- 21-1字符串相关api
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- c#WinForm程序调用vsto动态库,已解决
最近做一个vsto的项目,涉及到Form程序调用vsto动态库,弄了半天,搜了很多资料终于搞定了,把积累写下来备以后用.相关网址: https://stackoverflow.com/question ...
- sql (4) key and Join
新建表: "Persons" 表:Id_P LastName FirstName Address City1 Adams John Oxford Street London2 Bu ...
- apache 80 端口 反向代理 tomcat 8080端口
最近有个jsp的项目要放到服务上,但服务器上已经有了XAMPP(apache + mysql + php), 已占用了80端口.但http默认是访问80端口的. 先把tomcat 环境搭建起来, 发现 ...
- Mysql ---Sqlserver数据迁移到Mysql(Mysql建表迁移数据)
1 试用了MysqlWorkBench的数据迁移功能 以为能实现:建立跟Sqlserver一样的表结构和视图的功能,sqlserver的数据迁移到mysql 实际上发现:即使勾选了表和视图,实际上却只 ...