C++

动态数组

2017-06-17  本文已影响66人  saviochen

newdelete只能一次分配释放一个对象,一些场合,我们需要一次为很多对象分配内存,为了支持这种需求,C++标准库提供了两种方法:newallocator

1 new和数组

一些基本的语法

int *a = new int[get_size()];
int *a = new string[100]();
int *a = new string[10]{"a","b","c",string(3,'x')};
typedef int att[10];
int *a = new att;
delete []a;

智能指针和动态数组可以用unique_ptr管理动态数组,语法如下:

unique_ptr<int[]> up(new int[10]);
up[i] = 10;
up.release();//自动调用delete[]释放指针

\\此时,指向数组的unique ptr不支持成员访问运算符即 . 和 -> 运算符
\\其他unique ptr操作保持不变

unique_ptr不同,shared_ptr不支持直接管理动态数组,需要自己定义的删除器:

shared_ptr<int> sp(new int[10],[](int *p){delete []p;});//此处使用了lambda表达式
shared_ptr未定义下标运算符,并且不支持指针算术运算符
*(sp.get()+i) = i; //i为我们要访问的下标

2 allocator类

newdelete有一些灵活性的局限,将内存分配(释放)和对象构造(析构)组合在了一起,有时这会造成浪费。

标准库allocater类定义在头文件memory中,它帮助我们将对象构造和内存分配分离开,它提供一种类型感知的内存分配方法,它分配的内存是原始的,未构造的。

//定义allocator对象,它可以为类型为T的对象分配内存
allocator<T> a;

//分配一段原始的、未构造的内存,保存n个类型为T的对象
auto p = a.allocate(n);

//在p指向的内存中构造一个对象
a.construct(p,args);

//对p指向的对象执行析构函数
a.destroy(p);

//释放从T*指针 p中地址开始的内存,这块内存保存了n个对象;
//p必须先用allocate分配返回的指针,并且需要使用destroy析构对象后才能调用deallocate
a.deallocate(p,n);

以下为使用示例:

allocator<string> alloc;
auto const p = alloc.allocate(n);//分配n个未初始化的string

auto q = p;
alloc.construct(q++);//*p为空字符串

alloc.construct(q++,10,'c');//*p为cccccccccc

alloc.construct(q++,"h1");//*p为hi

while(q!=p)
    alloc.destroy(--q);//被销毁后,可以重新构造,注意是前置--
alloc.deallocate(p,n);

标准库还为allocator类定义了两个伴随算法,用来进行拷贝和填充操作:

//从迭代器b和e指出的范围中拷贝元素到迭代器b2开始的未构造内存中
uninitialized_copy(b,e,b2);

//将从迭代其b开始n个元素拷贝到迭代器b2开始的内存中
uninitialized_copy(b,n,b2);

//在迭代器b和e指出的范围中创建t的拷贝对象(多个)
uninitialized_fill(b,e,t);

//从b开始的内存中创建n个t对象
uninitialized_fill(b,n,t);
上一篇 下一篇

猜你喜欢

热点阅读