c++中的vector原理

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的内存,但是不会出现内存泄露;


==14367== Invalid read of size 1
==14367== at 0x3B7726CF1A: [email protected]@GLIBC_2.2.5 (in /lib64/libc-2.5.so)
==14367== by 0x3B7726234A: fwrite (in /lib64/libc-2.5.so)
==14367== 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.8)
==14367== by 0x403D9D: int traverse<char*>(std::vector<char*, std::allocator<char*> >) (testVector.cpp:33)
==14367== by 0x4013FA: f() (testVector.cpp:64)
==14367== by 0x4014FA: main (testVector.cpp:38)
==14367== Address 0x4e24481 is 1 bytes inside a block of size 1,024 free‘d
==14367== at 0x4A05D21: free (vg_replace_malloc.c:325)
==14367== by 0x401374: f() (testVector.cpp:60)
==14367== by 0x4014FA: main (testVector.cpp:38)
==14367==
0 ok
==14367==
==14367== HEAP SUMMARY:
==14367== in use at exit: 0 bytes in 0 blocks
==14367== total heap usage: 12 allocs, 13 frees, 2,220 bytes allocated
==14367==
==14367== All heap blocks were freed -- no leaks are possible
==14367==
==14367== For counts of detected and suppressed errors, rerun with: -v
==14367== Use --track-origins=yes to see where uninitialised values come from
==14367== ERROR SUMMARY: 9 errors from 8 contexts (suppressed: 4 from 4)

c++中的vector原理,布布扣,bubuko.com

时间: 2024-10-02 11:21:36

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

word2vec 中的数学原理详解

word2vec 中的数学原理详解 word2vec 是 Google 于 2013 年开源推出的一个用于获取 word vector 的工具包,它简单.高效,因此引起了很多人的关注.由于 word2vec 的作者 Tomas Mikolov 在两篇相关的论文 [3,4] 中并没有谈及太多算法细节,因而在一定程度上增加了这个工具包的神秘感.一些按捺不住的人于是选择了通过解剖源代码的方式来一窥究竟. 第一次接触 word2vec 是 2013 年的 10 月份,当时读了复旦大学郑骁庆老师发表的论文

caffe中HingeLossLayer层原理以及源码分析

输入: bottom[0]: NxKx1x1维,N为样本个数,K为类别数.是预测值. bottom[1]: Nx1x1x1维, N为样本个数,类别为K时,每个元素的取值范围为[0,1,2,-,K-1].是groundTruth. 输出: top[0]: 1x1x1x1维, 求得是hingeLoss. 关于HingeLoss: p: 范数,默认是L1范数,可以在配置中设置为L1或者L2范数. :指示函数,如果第n个样本的真实label为k,则为,否则为-1. tnk: bottom[0]中第n个样

word2vec 中的数学原理具体解释(三)背景知识

  word2vec 是 Google 于 2013 年开源推出的一个用于获取 word vector 的工具包,它简单.高效,因此引起了非常多人的关注.因为 word2vec 的作者 Tomas Mikolov 在两篇相关的论文 [3,4] 中并没有谈及太多算法细节,因而在一定程度上添加了这个工具包的神奇感.一些按捺不住的人于是选择了通过解剖源码的方式来一窥到底,出于好奇,我也成为了他们中的一员.读完代码后,认为收获颇多,整理成文,给有须要的朋友參考. 相关链接 (一)文件夹和前言 (二)预备

实战c++中的vector系列--再谈vector的insert()方法(都是make_move_iterator惹的祸)

之前说过了关于vector的insert()方法,把vector B的元素插入到vector A中,vector A中的结果我们可想而知,但是vector B中的元素还会如何? 看看之前写过的程序: #include <iostream> #include <vector> int main () { std::vector<int> myvector (3,100); std::vector<int>::iterator it; it = myvector

图像处理中的数学原理详解17——卷积定理及其证明

欢迎关注我的博客专栏"图像处理中的数学原理详解" 全文目录请见 图像处理中的数学原理详解(总纲) http://blog.csdn.net/baimafujinji/article/details/48467225 图像处理中的数学原理详解(已发布的部分链接整理) http://blog.csdn.net/baimafujinji/article/details/48751037 1.4.5   卷积定理及其证明 卷积定理是傅立叶变换满足的一个重要性质.卷积定理指出,函数卷积的傅立叶变

分布式系统中的CAP原理

分布式系统中的CAP原理,布布扣,bubuko.com

asp.net中session的原理及应用

Session简介丶特性 1.Session是一种Web会话中的常用状态之一. 2.Session提供了一种把信息保存在服务器内存中的方式.他能储存任何数据类型,包含自定义对象. 3.每个客户端的Seesion是独立存储的. 4.在整个会话过程中,只要SessionID的cookie不丢失,都会保存Session信息的. 5.Session不能跨进程访问,只能由该会话的用户访问.应为提取Session数据的id标识是以Cookie的方式保存到访问者浏览器的缓存里的. 6.当会话终止,或过期时,服

STL中的Vector相关用法

STL中的Vector相关用法 标准库vector类型使用需要的头文件:#include <vector>. vector 是一个类模板,不是一种数据类型,vector<int>是一种数据类型. Vector的存储空间是连续的,list不是连续存储的. 1. 定义和初始化 vector< typeName > v1; //默认v1为空,故下面的赋值是错误的v1[0]=5;//v2是v1的一个副本,若v1.size()>v2.size()则赋值后v2.size()被

linux中mmap系统调用原理分析与实现

参考文章:http://blog.csdn.net/shaoguangleo/article/details/5822110 linux中mmap系统调用原理分析与实现 1.mmap系统调用(功能)      void* mmap ( void * addr , size_t len , int prot , int flags ,int fd , off_t offset )      内存映射函数mmap, 负责把文件内容映射到进程的虚拟内存空间, 通过对这段内存的读取和修改,来实现对文件的