文章目录
需求
内存需要自动管理.
当我们用new/malloc申请一块内存的时候,往往有扩容的需求,
刚申请1M,希望保持其原有数据的情况下最追加数据。
我们知道std::string 能实现字符串的拼接,但是它一般用做字符串操作.
内存中可不能保证什么结尾是0.中间无0.不能直接用+=
但是我们可以用append()和assign()来实现.
我也曾经为此而困惑.最终测试出了最佳实践.显然我把它分享给你.
实现
为什么要使用std::string 来代替自己管理内存呢?
因为:它很方便.它能自动释放…
使其能管理0x00-0xff的数据.而不只是字符串.
最佳扩容方案: string.append(const char*p,size_t len); 追加,扩容
能在现有基础上追加:即std::string扩容:
const static size_t BUFFER_SIZE=256;
char* p = new char[BUFFER_SIZE]();
unsigned char j=0;//0-0xff
for(size_t i=0;i<BUFFER_SIZE;i++,j++){
p[i] = j;
}
std::string buffer; buffer.append(p,BUFFER_SIZE);
delete []p;
p=nullptr;
//此时查看buffer即可.
// 校验数据:
char* tmpP= buffer.c_str();
unsigned char j=0;//0-0xff
for(size_t i=0;i<BUFFER_SIZE;i++,j++){
if(tmpP[i] != j){
throw("数据错误")
}
}
//suc
注意: 虽然是废话但还是要提醒:扩容后的指针非常可能会变化,
每次使用append,要重新通过 buffer.c_str()获取指针
最佳重置方案: string.assign(const char*p,size_t len); 初始化.
和赋值操作符一样.
也就是说会把之前添加的数据都给抹去了!
方案一 一个字节一个字节的加
···
std::string str;
str += ‘0x1’;
···
这种方式的主要特点就是慢.添加40M数据 耗时如下表:
用法 | 耗时 | 测试大小 |
---|---|---|
vector | 49s | 40M |
string | 36s | 40M |
方案二 先resize改变空间/reserve预留空间,然后memcpy的方式
这是一个非常好的思路.但是有更好效率的方式,效率慢一点是因为:
resize+memcpy涉及2次内存填充.
方案三 string.assign 效率高:但是它能保护原数据吗?能以追加方式添加吗?这是我的疑惑.
assign则只有一次内存填充。 首推.
方案四 利用C函数实现管理:relloc 实现数据自动复制和扩容
先malloc,
再按照需求relloc
只所以开始没有找到这个方案,是因为对relloc了解不清楚和误解,
以为这个函数会在函数会保持内存地址不变.这样就没有什么潜力了.
但是这个函数是从堆中找,会挑选合适的地方.
方案五:自己实现内存管理.
主要是大内存申请就行.
我们的需求并不多:
c_str();
push(const char*,size_t len)
就OK了.