vector
vector就是动态数组.它也是在堆中分配内存,元素连续存放,有保留内存,如果减少大小后,内存也不会释放.如果新值>当前大小时才会再分配内存.

它拥有一段连续的内存空间,并且起始地址不变,因此它能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外,当该数组后的内存空间不够时,需要重新申请一块足够大的内存并进行内存的拷贝。这些都大大影响了vector的效率。

对最后元素操作最快(在后面添加删除最快 ), 此时一般不需要移动内存,只有保留内存不够时才需要

对中间和开始处进行添加删除元素操作需要移动内存,如果你的元素是结构或是类,那么移动的同时还会进行构造和析构操作,所以性能不高 (最好将结构或类的指针放入vector中,而不是结构或类本身,这样可以避免移动时的构造与析构)。
访问方面,对任何元素的访问都是O(1),也就是是常数的,所以vector常用来保存需要经常进行随机访问的内容,并且不需要经常对中间元素进行添加删除操作.

相比较可以看到vector的属性与string差不多,同样可以使用capacity看当前保留的内存,使用swap来减少它使用的内存.

capacity()返回vector所能容纳的元素数量

例如下面的代码


#include <iostream>
#include <vector>
using namespace std;
class A{
char *p;
public: A();
~A();
};

template<typename T>

int traverse(vector<T> vecData){
typename vector<T>::iterator it;
int i=0;
//for(T::size_type i=0;it!=vecData.end();it++,i++)
for (it = vecData.begin(); it != vecData.end(); ++it)
cout<<"\t"<<i<<"\t"<<*it<<endl;
}
A::A(){p=(char *)malloc(sizeof(char) * 1024);}
A::~A(){free(p);}
int f();
int main(){f();}
int f(){
A o;
vector<string> vecData;
vector<char*> vecPtr;
char *a=(char *)malloc(sizeof(char) * 1024);
a[0]='o';
a[1]='k';
a[3]='\0';
string data="1234";
vecData.push_back(data);
cout<<"vecData[0]\t"<<vecData[0]<<"\tcapacity:\t"<<vecData.capacity()<<endl;
data.clear();
data="4321";
vecData.push_back(data);
cout<<"vecData[1]\t"<<vecData[1]<<"\tcapacity:\t"<<vecData.capacity()<<endl;
data.clear();
std::sort(vecData.begin(),vecData.end());
traverse(vecData);
vecPtr.push_back(a);
cout<<"before ptr vector release"<<endl;
traverse(vecPtr);
free(a);
a=NULL;
cout<<"after ptr vector release"<<endl;
traverse(vecPtr);
}

 

此时运行valgrind:

(1)不会出现vecData内存未释放的情况,说明vector对象析构函数在退出的时候自动进行了调用;

(2)不会出现因为删除掉data就导致读不到vector中内容的情况,说明在push_back增加元素的时候进行了拷贝操作,即使是原有数据删除也不会影响;

(3)当vector中的元素为指针的时候,拷贝的是指针本身,而不是指针指向的对象,此时释放掉指针对象的空间,那么vector中的元素就找不到地址,用valgrind会告诉说访问已经free的内存,但是不会出现内存泄露;

==== Invalid read of size
==== at 0x3B7726CF1A: _IO_file_xsputn@@GLIBC_2.2.5 (in /lib64/libc-2.5.so)
==== by 0x3B7726234A: fwrite (in /lib64/libc-2.5.so)
==== by 0x3E95690310: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (in /usr/lib64/libstdc++.so.6.0.)
==== by 0x403D9D: int traverse<char*>(std::vector<char*, std::allocator<char*> >) (testVector.cpp:)
==== by 0x4013FA: f() (testVector.cpp:)
==== by 0x4014FA: main (testVector.cpp:)
==== Address 0x4e24481 is bytes inside a block of size , free'd
==== at 0x4A05D21: free (vg_replace_malloc.c:)
==== by 0x401374: f() (testVector.cpp:)
==== by 0x4014FA: main (testVector.cpp:)
====
ok
====
==== HEAP SUMMARY:
==== in use at exit: bytes in blocks
==== total heap usage: allocs, frees, , bytes allocated
====
==== All heap blocks were freed -- no leaks are possible
====
==== For counts of detected and suppressed errors, rerun with: -v
==== Use --track-origins=yes to see where uninitialised values come from
==== ERROR SUMMARY: errors from contexts (suppressed: from )

c++中的vector原理的更多相关文章

  1. word2vec中的数学原理一 目录和前言

    最近在看词向量了,因为这个概念对于语言模型,nlp都比较重要,要好好的学习一下.把网上的一些资料整合一下,搞个系列. 主要参考:    word2vec 中的数学原理详解                ...

  2. 【转】java.util.vector中的vector的详细用法

    [转]java.util.vector中的vector的详细用法 ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.uti ...

  3. 广告系统中weak-and算法原理及编码验证

    wand(weak and)算法基本思路 一般搜索的query比较短,但如果query比较长,如是一段文本,需要搜索相似的文本,这时候一般就需要wand算法,该算法在广告系统中有比较成熟的应 该,主要 ...

  4. ABP中动态WebAPI原理解析

    ABP中动态WebAPI原理解析 动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类 ...

  5. Mysql中主从复制的原理、配置过程以及实际案例

    Mysql中主从复制的原理.配置过程以及实际案例1.什么是主从复制?原理:主从分离,什么意思呢?我们不妨画个图看看.如图1所示: 2.准备工作:预备两台服务器,我这里使用虚拟机安装了两个Centos6 ...

  6. 转:用STL中的vector动态开辟二维数组

    用STL中的vector动态开辟二维数组 源代码:#include <iostream>#include <vector>using namespace std;int mai ...

  7. JavaScript中new实现原理

    JavaScript中new实现原理 1.创建一个空对象 obj 2.将该对象 obj 的原型链 __proto__ 指向构造函数的原型 prototype, 并且在原型链 __proto__ 上设置 ...

  8. 浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理

    浅谈范德蒙德(Vandermonde)方阵的逆矩阵与拉格朗日(Lagrange)插值的关系以及快速傅里叶变换(FFT)中IDFT的原理 标签: 行列式 矩阵 线性代数 FFT 拉格朗日插值 只要稍微看 ...

  9. word2vec 中的数学原理三 背景知识 语言模型

    主要参考:    word2vec 中的数学原理详解                 自己动手写 word2vec

随机推荐

  1. Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.5

    Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.5 or one of ...

  2. Cocos2d 3.0继承自Sprite的类在addChild后出现故障

    当继承自Sprite的类被addChild到其它的Node里后出现例如以下图问题,说明没有调用父类Sprite::init()的方法.由于父类Sprite里的_textureAtlas须要初始化为nu ...

  3. Linux操作系统分析 ------------------中国科技大学

    http://teamtrac.ustcsz.edu.cn/wiki/Linux2014

  4. bash手册 之重定向原理与实现

    http://www.gnu.org/software/bash/manual/bashref.html#Redirections http://www.cnblogs.com/weidagang20 ...

  5. UNIX环境高级编程---标准I/O库

    前言:我想大家学习C语言接触过的第一个函数应该是printf,但是我们真正理解它了吗?最近看Linux以及网络编程这块,我觉得I/O这块很难理解.以前从来没认识到Unix I/O和C标准库I/O函数压 ...

  6. 第二次装OA系统

    第二次安装:1.解压之后再MYOA目录下 找到一键安装.bat2.安装之后,一闪而过.(电脑上不需要apache,也不需要 mysql)3.192.168.1.111(自己电脑IP)看是否可以,若不可 ...

  7. windows 进程间通讯方法

    Windows平台为我们提供了多种进程间通信的机制,主要包括:注册表方式.共享文件方式.共享内存方式.共享数据段.映射文件方式.管道方式. 剪贴板方式.消息方式.其中注册表方式需要增加注册表表项,而注 ...

  8. 文件权限和目录权限详解(rwx)

    [文件] r:可读,可以使用cat命令查看文件内容: w:可写,可以编辑或删除文件: x:可执行,可以当作命令提交给内核 [目录] r:可以对此目录执行ls,列出内部所有文件 w:可以在此目录创建文件 ...

  9. radio的change事件

    radio的change事件 <scripttype="text/javascript"> $(document).ready(function(){ $(" ...

  10. Oracle创建存储过程、执行存储过程基本语法

    >>>>>>>>>>>>>>>>>>>>>>>>> ...