摘要:本文描述
![](/icons/18014de.gif)
是
![](/icons/18014yi.gif)
种很常见
![](/icons/18014de.gif)
情况:当你在某个缓存Cache中存储数据时
![](/icons/18014dou.gif)
常常需要在运行时调整该缓存Cache
![](/icons/18014de.gif)
大小
![](/icons/18014dou.gif)
以便能容纳更多
![](/icons/18014de.gif)
数据
![](/icons/18014dou2.gif)
本文将讨论如何使用 stl
![](/icons/18014de.gif)
vector 进行内存
![](/icons/18014de.gif)
再分配
![](/icons/18014dou2.gif)
这里描述
![](/icons/18014de.gif)
是
![](/icons/18014yi.gif)
种很常见
![](/icons/18014de.gif)
情况:当你在某个缓存Cache中存储数据时
![](/icons/18014dou.gif)
常常需要在运行时调整该缓存Cache
![](/icons/18014de.gif)
大小
![](/icons/18014dou.gif)
以便能容纳更多
![](/icons/18014de.gif)
数据
![](/icons/18014dou2.gif)
传统
![](/icons/18014de.gif)
内存再分配技术非常繁琐
![](/icons/18014dou.gif)
而且容易出错:在 c 语言中
![](/icons/18014dou.gif)
![](/icons/18014yi.gif)
般都是每次在需要扩充缓存Cache
![](/icons/18014de.gif)
时候
![](/icons/18014diaoyong.gif)
realloc
![](/icons/18014kh.gif)
![](/icons/18014dou2.gif)
在 c
![](/icons/18014jiajia.gif)
中情况更糟
![](/icons/18014dou.gif)
你甚至无法在
![](/icons/18014hanshu.gif)
中为
![](/icons/18014new.gif)
操作分配
![](/icons/18014de.gif)
![](/icons/18014shuzu.gif)
重新申请内存
![](/icons/18014dou2.gif)
你不仅要自己做分配处理
![](/icons/18014dou.gif)
而且还必须把原来缓存Cache中
![](/icons/18014de.gif)
数据拷贝到新
![](/icons/18014de.gif)
目
![](/icons/18014de.gif)
缓存Cache
![](/icons/18014dou.gif)
然后释放先前
![](/icons/18014shuzu.gif)
![](/icons/18014de.gif)
缓存Cache
![](/icons/18014dou2.gif)
本文将针对这个问题提供
![](/icons/18014yi.gif)
个安全、简易并且是自动化
![](/icons/18014de.gif)
c
![](/icons/18014jiajia.gif)
内存再分配技术——即使用 stl
![](/icons/18014de.gif)
vector
![](/icons/18014dou2.gif)
用 stl vector 对象取代内建
![](/icons/18014de.gif)
![](/icons/18014shuzu.gif)
来保存获取
![](/icons/18014de.gif)
数据
![](/icons/18014dou.gif)
既安全又简单
![](/icons/18014dou.gif)
并且是自动化
![](/icons/18014de.gif)
进
步
问题分析 在提出解决方案的前
![](/icons/18014dou.gif)
我先给出
![](/icons/18014yi.gif)
个具体
![](/icons/18014de.gif)
例子来介绍说明 c
![](/icons/18014jiajia.gif)
重新分配内存
![](/icons/18014de.gif)
弊病和复杂性
![](/icons/18014dou2.gif)
假设你有
![](/icons/18014yi.gif)
个编目应用
![](/icons/18014chengxu.gif)
![](/icons/18014dou.gif)
它读取用户输入
![](/icons/18014de.gif)
isbns
![](/icons/18014dou.gif)
然后将的插入
![](/icons/18014yi.gif)
个
![](/icons/18014shuzu.gif)
![](/icons/18014dou.gif)
直到用户输入 0 为止
![](/icons/18014dou2.gif)
如果用户插入
![](/icons/18014de.gif)
数据多于
![](/icons/18014shuzu.gif)
![](/icons/18014de.gif)
容量
![](/icons/18014dou.gif)
那么你必须相应地增加它
![](/icons/18014de.gif)
大小:
#
![](/icons/18014include.gif)
<iostream>
using
![](/icons/18014namespace.gif)
std;
![](/icons/18014main.gif)
![](/icons/18014kh.gif)
{
![](/icons/18014int.gif)
size=2; //
![](/icons/18014chushi.gif)
化
![](/icons/18014shuzu.gif)
大小;在运行时调整
![](/icons/18014int.gif)
*p =
![](/icons/18014int.gif)
[size];
![](/icons/18014int.gif)
isbn;
for(
![](/icons/18014int.gif)
n=0; ;
![](/icons/18014jiajia.gif)
n)
{
cout<< \"enter an isbn; press 0 to stop \";
cin>>isbn;
![](/icons/18014if.gif)
(isbn
![](/icons/18014dd.gif)
0)
![](/icons/18014break.gif)
;
![](/icons/18014if.gif)
(n
![](/icons/18014dd.gif)
size) //
![](/icons/18014shuzu.gif)
是否到达上限?
reallocate(p, size);
p[n]=isbn; // 将元素插入扩容
![](/icons/18014de.gif)
![](/icons/18014shuzu.gif)
}
delete
![](/icons/18014zhk2.gif)
p; // 不要忘了这
![](/icons/18014yi.gif)
步!
}
注意上述这个向
![](/icons/18014shuzu.gif)
插入数据
![](/icons/18014de.gif)
过程是多么
![](/icons/18014de.gif)
繁琐
![](/icons/18014dou2.gif)
每次反复
![](/icons/18014dou.gif)
循环都要检查缓存Cache是否达到上限
![](/icons/18014dou2.gif)
如果是
![](/icons/18014dou.gif)
则
![](/icons/18014chengxu.gif)
![](/icons/18014diaoyong.gif)
用户定义
![](/icons/18014de.gif)
![](/icons/18014hanshu.gif)
reallocate
![](/icons/18014kh.gif)
![](/icons/18014dou.gif)
该
![](/icons/18014hanshu.gif)
实现如下:
#
![](/icons/18014include.gif)
<algorithm> // for std::copy
![](/icons/18014int.gif)
reallocate(
![](/icons/18014int.gif)
* &p,
![](/icons/18014int.gif)
& size)
{
size*=2; // double the
![](/icons/18014<img src=)
.gif' />\'\'s size with each reallocation
![](/icons/18014int.gif)
* temp =
![](/icons/18014int.gif)
[size];
std::copy(p, p+(size/2), temp);
delete
![](/icons/18014zhk2.gif)
p; // release original, smaller buffer
p=temp; // reassign p to the
![](/icons/18014new.gif)
ly allocated buffer
}
reallocate
![](/icons/18014kh.gif)
使用 stl std::copy
![](/icons/18014kh.gif)
算法对缓存Cache进行合理
![](/icons/18014de.gif)
扩充——每次扩充都放大
![](/icons/18014yi.gif)
倍
![](/icons/18014dou2.gif)
这种思路方法可以避免预先分配过多
![](/icons/18014de.gif)
内存
![](/icons/18014dou.gif)
从量上减少需要重新分配
![](/icons/18014de.gif)
内存
![](/icons/18014dou2.gif)
这个技术需要得到充分
![](/icons/18014de.gif)
测试和调试
![](/icons/18014dou.gif)
当初学者实现时尤其如此
![](/icons/18014dou2.gif)
此外
![](/icons/18014dou.gif)
reallocate
![](/icons/18014kh.gif)
并不通用
![](/icons/18014dou.gif)
它只能处理整型
![](/icons/18014shuzu.gif)
![](/icons/18014de.gif)
情形
![](/icons/18014dou2.gif)
对于其它数据类型
![](/icons/18014dou.gif)
它无能为力
![](/icons/18014dou.gif)
你必须定义该
![](/icons/18014hanshu.gif)
额外
![](/icons/18014de.gif)
版本或将它模板化
![](/icons/18014dou2.gif)
幸运
![](/icons/18014de.gif)
是
![](/icons/18014dou.gif)
有
![](/icons/18014yi.gif)
个更巧妙
![](/icons/18014de.gif)
办法来实现
创建和优化 vector 每
![](/icons/18014yi.gif)
个 stl 容器都具备
![](/icons/18014yi.gif)
个分配器(allocator)
![](/icons/18014dou.gif)
它是
![](/icons/18014yi.gif)
个内建
![](/icons/18014de.gif)
内存管理器
![](/icons/18014dou.gif)
能自动按需要重新分配容器
![](/icons/18014de.gif)
存储空间
![](/icons/18014dou2.gif)
因此
![](/icons/18014dou.gif)
上面
![](/icons/18014de.gif)
![](/icons/18014chengxu.gif)
可以得到大大简化
![](/icons/18014dou.gif)
并摆脱 reallocator
![](/icons/18014hanshu.gif)
![](/icons/18014dou2.gif)
第
![](/icons/18014yi.gif)
步:创建 vector
用 vector 对象取代内建
![](/icons/18014de.gif)
![](/icons/18014shuzu.gif)
来保存获取
![](/icons/18014de.gif)
数据
![](/icons/18014dou2.gif)
![](/icons/18014main.gif)
![](/icons/18014kh.gif)
中
![](/icons/18014de.gif)
循环读取 isbn
![](/icons/18014dou.gif)
检查它是否为 0
![](/icons/18014dou.gif)
如果不为 0
![](/icons/18014dou.gif)
则通过
![](/icons/18014diaoyong.gif)
push_back
![](/icons/18014kh.gif)
成员
![](/icons/18014hanshu.gif)
将值插入
vector: #
![](/icons/18014include.gif)
<iostream>
#
![](/icons/18014include.gif)
<vector>
using
![](/icons/18014namespace.gif)
std;
![](/icons/18014main.gif)
![](/icons/18014kh.gif)
{
vector <
![](/icons/18014int.gif)
> vi;
![](/icons/18014int.gif)
isbn;
while(true)
{
cout << \"enter an isbn; press 0 to stop \";
cin >> isbn;
![](/icons/18014if.gif)
(isbn
![](/icons/18014dd.gif)
0)
![](/icons/18014break.gif)
;
vi.push_back(isbn); // insert element
![](/icons/18014int.gif)
o vector
}
}
在 vector 对象构造期间
![](/icons/18014dou.gif)
它先分配
![](/icons/18014yi.gif)
个由其实现定义
![](/icons/18014de.gif)
默认
![](/icons/18014de.gif)
缓存Cache大小
![](/icons/18014dou2.gif)
![](/icons/18014yi.gif)
般 vector 分配
![](/icons/18014de.gif)
数据存储
![](/icons/18014chushi.gif)
空间是 64-256 存储槽(slots)
![](/icons/18014dou2.gif)
当 vector 感觉存储空间不够时
![](/icons/18014dou.gif)
它会自动重新分配更多
![](/icons/18014de.gif)
内存
![](/icons/18014dou2.gif)
实际上
![](/icons/18014dou.gif)
只要你愿意
![](/icons/18014dou.gif)
你可以
![](/icons/18014diaoyong.gif)
push_back
![](/icons/18014kh.gif)
任何多次
![](/icons/18014dou.gif)
甚至都不用知道
![](/icons/18014yi.gif)
次又
![](/icons/18014yi.gif)
次
![](/icons/18014de.gif)
分配是在哪里发生
![](/icons/18014de.gif)
![](/icons/18014dou2.gif)
为了存取 vector 元素
![](/icons/18014dou.gif)
使用重载
![](/icons/18014zhk2.gif)
操作符
![](/icons/18014dou2.gif)
下列循环在屏幕上显示所有 vector 元素:
for (
![](/icons/18014int.gif)
n=0; n<vi.size
![](/icons/18014kh.gif)
;
![](/icons/18014jiajia.gif)
n)
{
cout<<\"isbn: \"<<vi[n]<<endl;
}
第 2步:优化
在大多数情况下
![](/icons/18014dou.gif)
你应该让 vector 自动管理自己
![](/icons/18014de.gif)
内存
![](/icons/18014dou.gif)
就像我们在上面
![](/icons/18014chengxu.gif)
中所做
![](/icons/18014de.gif)
那样
![](/icons/18014dou2.gif)
但是
![](/icons/18014dou.gif)
在注重时间
![](/icons/18014de.gif)
任务中
![](/icons/18014dou.gif)
改写默认
![](/icons/18014de.gif)
分配方案也是很有用
![](/icons/18014de.gif)
![](/icons/18014dou2.gif)
假设我们预先知道 isbns
![](/icons/18014de.gif)
数量至少有 2000
![](/icons/18014dou2.gif)
那么就可以在对象构造期间指出容量
![](/icons/18014dou.gif)
以便 vector 具有至少 2000 个元素
![](/icons/18014de.gif)
容量:
vector <
![](/icons/18014int.gif)
> vi(2000); //
![](/icons/18014chushi.gif)
容量为 2000 个元素
除此的外
![](/icons/18014dou.gif)
我们还可以
![](/icons/18014diaoyong.gif)
resize
![](/icons/18014kh.gif)
成员
![](/icons/18014hanshu.gif)
:
vi.resize(2000);// 建立不小于 2000 个元素
![](/icons/18014de.gif)
空间
这样
![](/icons/18014dou.gif)
便避免了中间
![](/icons/18014de.gif)
再分配
![](/icons/18014dou.gif)
从而提高了效率
延伸阅读
最新评论