vector的内存分配与释放
1. vector内存分配
《Effective STL》中“条款14”:使用reserve来避免不必要的重新分配
关于STL容器,最神奇的事情之一是只要不超过它们的最大大小,它们就可以自动增长到足以容纳你放进去的数据。(要知道这个最大值,只要调用名叫max_size的成员函数。)对于vector和string,只要需要更多空间,就以realloc等价的思想来增长。这个类似于realloc的操作有四个部分:
- 分配新的内存块,它有容器目前容量的几倍。在大部分实现中,vector和string的容量每次以2为因数增长。也就是说,当容器必须扩展时,它们的容量每次翻倍。
- 把所有元素从容器的旧内存拷贝到它的新内存。
- 销毁旧内存中的对象。
- 回收旧内存。
给了所有的分配,回收,拷贝和析构,你就应该知道那些步骤都很昂贵。当然,你不会想要比必须的更为频繁地执行它们。如果这没有给你打击,那么也许当你想到每次这些步骤发生时,所有指向vector或string中的迭代器、指针和引用都会失效时,它会给你打击的。这意味着简单地把一个元素插入vector或string的动作也可能因为需要更新其他使用了指向vector或string中的迭代器、指针或引用的数据结构而膨胀。
DEMO:
#include <QtCore/QCoreApplication>
#include <QDebug>
#include <vector> using namespace std; class Person
{
public:
Person(QString str)
{
m_str=str;
qDebug()<< "construction:"<<m_str;
}
Person(const Person& p)
{
this->m_str=p.m_str;
qDebug()<< "copy construction:"<<m_str;
}
~Person()
{
qDebug()<< "destruction:"<<m_str;
}
private:
QString m_str;
}; int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
{
vector<Person> V;
//V.reserve(10); qDebug()<<"MaxSize :"<<V.max_size()<<"Capacity :"<<V.capacity(); Person a("a");
Person b("b");
Person c("c"); qDebug()<<" push :a";
V.push_back(a);
qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();
qDebug()<<" push :b";
V.push_back(b);
qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();
qDebug()<<" push :c";
V.push_back(c);
qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity(); V.clear();
qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity(); //
//vector<Person>(V).swap(V);
//qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();
} return app.exec();
}

添加reserve:
V.reserve();

插入新项时就不用重新拷贝构造 b和c了,提高效率。
2. vector内存释放
《Effective STL》中“条款17”:使用“交换技巧”来修整过剩容量
当vector、string大量插入数据后,即使删除了大量数据(或者全部都删除,即clear) 并没有改变容器的容量(capacity),所以仍然会占用着内存。 为了避免这种情况,我们应该想办法改变容器的容量使之尽可能小的符合当前 数据所需(shrink to fit)
《Effective STL》给出的解决方案是:
即先创建一个临时拷贝与原先的vector一致,值得注意的是,此时的拷贝 其容量是尽可能小的符合所需数据的。紧接着将该拷贝与原先的vector v进行 交换。好了此时,执行交换后,临时变量会被销毁,内存得到释放。此时的v即为原先 的临时拷贝,而交换后的临时拷贝则为容量非常大的vector(不过已经被销毁)
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
{
vector<int> V; for(int i=;i<;i++)
{V.push_back(i);}
qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity(); qDebug()<<"Clear:";
V.clear();
qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity(); qDebug()<<"Swap(V):";
vector<int>(V).swap(V);
qDebug()<<"Size :"<<V.size()<<"Capacity :"<<V.capacity();
}
return app.exec();
}

vector的内存分配与释放的更多相关文章
- (转)C++ STL中的vector的内存分配与释放
C++ STL中的vector的内存分配与释放http://www.cnblogs.com/biyeymyhjob/archive/2012/09/12/2674004.html 1.vector的内 ...
- C语言中的内存分配与释放
C语言中的内存分配与释放 对C语言一直都是抱着学习的态度,很多都不懂,今天突然被问道C语言的内存分配问题,说了一些自己知道的,但感觉回答的并不完善,所以才有这篇笔记,总结一下C语言中内存分配的主要内容 ...
- DLL函数中内存分配及释放的问题
DLL函数中内存分配及释放的问题 最近一直在写DLL,遇到了一些比较难缠的问题,不过目前基本都解决了.主要是一些内存分配引起问题,既有大家经常遇到的现象也有特殊的 情况,这里总结一下,做为资料. 错误 ...
- 内存管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现
http://blog.csdn.net/pi9nc/article/details/23334659 注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料 ...
- Com组件的内存分配和释放,CredentialProvider SHStrDup 字符串拷贝问题
一.简单介绍 熟悉CredentialProvider的同学应该知道,他为一个Com组件,于是,在这里的内存分配(字符串拷贝)的一系列操作就要依照con的标准来. 二.Com组件的内存分配和释放 CO ...
- C++内存分配与释放
C++内存分配与释放 1. new 运算符 与 operator new一条 new 表达式语句( new Type; )中的 new 是指 new 运算符.operator new 是定义在 #in ...
- C++学习011-常用内存分配及释放函数
C++用有多种方法来分配及释放内存,下面是一些经常使用的内存分配及释放函数 现在我还是一个技术小白,一般用到也指示 new+delete 和 malloc和free 其他的也是在学习中看到,下面的文字 ...
- vector的内存分配机制分析
该程序初步演示了我对vector在分配内存的时候的理解.可能有误差,随着理解的改变,改代码可以被修改. /* 功能说明: vector的内存分配机制分析. 代码说明: vector所管理的内存地址是连 ...
- C/C++动态二维数组的内存分配和释放
C语言: 1 //二维数组动态数组分配和释放 //数组指针的内存分配和释放 //方法一 char (*a)[N];//指向数组的指针 a = (char (*)[N])malloc(sizeof(ch ...
随机推荐
- Unity 代码检测单击,双击,拖放
今天小伙伴问我如何自己写一段代码检测 单击 双击 和 拖放.于是就写了这段代码O(∩_∩)O~ 代码如下: using UnityEngine; using System.Collections; p ...
- phonegap环境配置与基本操作
一.开发环境配置: 1.工具环境安装: 安装java sdk 1.6以上版本号,Android Development Tools.ant,系统变量 Path后面加入 新增名稱 JAVA_HOME 值 ...
- js中json的转换
//aa='{"id":0,"appId":"app***********Id","appSecret":"a ...
- HTML与CSS入门——第二章 发布Web内容
知识点: 1.使用文本编辑器创建一个基本的HTML文件的方法 2.使用FTP将文件传送到你的Web服务器的方法 3.文件在Web服务器上应该存储的位置 4.在没有Web服务器的情况下分发Web内容的方 ...
- MySQL的字符串函数截取字符
函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例:select left(content,200) as abstract from my ...
- PHP学习笔记三十七【http】
<?php print_r($_SERVER); //$_SERVER预编译变量[数组]输出请求报文,注意大小写 echo "<br/>"; foreach($_ ...
- iOS 之 cocoapods安装与使用
我们都知道第三方库,一般使用cocoapods管理,cocoapods在我们IOS开发中有着很大的作用. 好了,现在看下它的安装步骤: 1.打开终端,输入 sudo gem install cocoa ...
- 使用正则表达式限制swing (JTextField等) 的输入
之前使用Qt编写Gui程序的时候,可以直接使用正则表达式限制所有输入框,非常方便. 这段时间要做一份课程设计,使用java编写,ui要限制输入,比如只能输入x位数字,输入身份证等. 百度了许多资料,发 ...
- 读《疯狂Ajax讲义》重点
1.XMLHttpRequest() 请求的写法(p62) 一个类XMLHttp 因该包含的接口:[1] XMLHttp.sendRequest("POST",URL,data, ...
- 使用JavaScript判断图片是否加载完成的三种实现方式
有时需要获取图片的尺寸,这需要在图片加载完成以后才可以.有三种方式实现,下面一一介绍. 一.load事件 <!DOCTYPE HTML> <html> <head> ...