博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vector重新申请内存
阅读量:2354 次
发布时间:2019-05-10

本文共 2443 字,大约阅读时间需要 8 分钟。

其实这里我们可以看到,vector所占据的内存,并不是通过size()函数查看的,而是通过capacity()函数查看的,而erase()、pop_back()和clear()函数(pop_back、clear底层均用erase实现)改变的仅仅是size()函数的返回值,并没有清除存储空间。

清除空间的方式:

vector<int> ().swap(name);

#include
#include
using namespace std;int main(){ vector
vec; cout << "capacity: " << vec.capacity() << endl; cout << "size: " << vec.size() << endl; vec.push_back(1); vec.push_back(1); vec.push_back(1); cout << "capacity: " << vec.capacity() << endl; cout << "size: " << vec.size() << endl; vec.pop_back(); cout << "capacity: " << vec.capacity() << endl; cout << "size: " << vec.size() << endl; vec.clear(); cout << "capacity: " << vec.capacity() << endl; cout << "size: " << vec.size() << endl; vector
().swap(vec); cout << "capacity: " << vec.capacity() << endl; cout << "size: " << vec.size() << endl; system("pause"); return 0;}

一、realloc函数介绍

realloc原型是externvoid *realloc(void *mem_address, unsigned int newsize);

先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

二、vector重新申请内存策略

对于vector和string,只要需要更多空间,就以realloc等价的思想来增长。这个类似于realloc的操作有四个部分:

1. 分配新的内存块,它有容器目前容量的几倍。在大部分实现中,vector和string的容量每次以2为因数增长。也就是说,当容器必须扩展时,它们的容量每次翻倍。

2. 把所有元素从容器的旧内存拷贝到它的新内存。

3. 销毁旧内存中的对象。

4. 回收旧内存。

reserve成员函数允许你最小化必须进行的重新分配的次数,因而可以避免真分配的开销和迭代器/指针/引用失效。在标准容器中,只有vector和string提供了所有这些函数。

● size()告诉你容器中有多少元素。它没有告诉你容器为它容纳的元素分配了多少内存。

● capacity()告诉你容器在它已经分配的内存中可以容纳多少元素。那是容器在那块内存中总共可以容纳多少元素,而不是还可以容纳多少元素。如果你想知道一个vector或string中有多少没有被占用的内存,你必须从capacity()中减去size()。如果size和capacity返回同样的值,容器中就没有剩余空间了,而下一次插入(通过insert或push_back等)会引发上面的重新分配步骤。

● resize(Container::size_type n)强制把容器改为容纳n个元素。调用resize之后,size将会返回n。如果n小于当前大小,容器尾部的元素会被销毁。如果n大于当前大小,新默认构造的元素会添加到容器尾部。如果n大于当前容量,在元素加入之前会发生重新分配。

● reserve(Container::size_type n)强制容器把它的容量改为至少n,提供的n不小于当前大小。这一般强迫进行一次重新分配,因为容量需要增加。(如果n小于当前容量,vector忽略它,这个调用什么都不做,string可能把它的容量减少为size()和n中大的数,但string的大小没有改变。)

vector
v;v.reserve(1000);// 如果没有此行代码,将会进行10多次的内存重新分配,也就是10多次扩充数组大小for (int i = 1; i <= 1000; ++i) v.push_back(i);

#include
#include
using namespace std;int main(){ vector
v; for (int i = 1; i < 100; i++) { if (v.size() == v.capacity()) //通过对size和capacity的比较,可以判断什么时候发生内存重新分配 { cout << "capacity:" << v.capacity() << ", " << "size" << v.size() << endl; } v.push_back(i); } system("pause"); return 0;}

你可能感兴趣的文章
多核危机:Scala vs. Erlang
查看>>
未来系统中的编程语言
查看>>
函数式编程另类指南1
查看>>
kudu tablet design(kudu表设计)
查看>>
kudu master design(kudu主节点设计)
查看>>
第七章:druid.io实践分享之realtime+kafka 一
查看>>
第七章:druid.io实践分享之Realtime+kafka 二
查看>>
Java内存管理
查看>>
Maven配置资料(一)
查看>>
Maven配置资料(二)
查看>>
程序设计语言发展回顾与展望
查看>>
服务器开发总结
查看>>
web.xml的相关说明
查看>>
WPARAM 和 LPARAM,消息响应机制
查看>>
java设置时区问题
查看>>
安装postgresQL Query Cache
查看>>
PostgreSQL Memory for Database Caching(1)
查看>>
PostgreSQL Memory for Database Caching(2)
查看>>
函数式编程扫盲篇
查看>>
PostgreSQL Query 优化体验
查看>>