构建方式
1.原始的new,delete方式
2.标准库的allocator类
最好使用标准库,简单而且不易出现内存管理错误
new方式
1.[]里不用填常量,只要是整数就行
int *p= new int[get_size()];
2.返回的类型是指针而不是数组
3.初始化方式
int *p1 = new int[10]; //默认初始化,内置类型值未定义
int *p2 = new int[10](); //值初始化,默认值为0
int *p3 = new int[10]{0,1,2,3,4,5,6,7,8,9}; //列表初始化
4.释放数组
要想保证正确,就加上[]。我以前还研究好久如果不加[]会发生啥问题,现在想想没必要,按标准来就行。
delete p; // 不是数组就别加了
delete []pa; //严格按数组就加[]
智能指针与动态数组
unique_ptr<int []>
标准库用unique_ptr<int []>方式管理动态数组,最后会自动调用delete[]。
访问比较简单
shared_ptr<int> 方式
默认使用delete删除对象,所以得写个删除器
shared_ptr<int> sp (new int[10], [](int *p){delete []p; });
sp.reset(); //调用删除器
访问比较麻烦
allocator类
动机
前面的new是内存分配和对象构造同时做了,所以现在要想内存分配和对象构造分离,就用标准库的allocator。
分配内存
只是分配一段内存,没初始化
allocator<string> a;
int n =10;
auto const p = a.allocate(n); //
构造对象
分配完内存就必须构造对象才有意义
auto q = p;
a.construct(q, 10,'c'); //构造一个对象
删除对象
a.destroy(q); //删除一个对象,会调用析构
回收内存
回收内存前先调用destroy。
a.deallocate(p, n); //
一下子构造多个对象
前面的construct一次只能构造一个对象,实在麻烦。
以上函数是专门给未初始化的内存准备的,不要再想着非得用到初始化内存身上发生啥事。
allocator<string> a;
vector<int> vi = {0,1};
auto p = a.allocate(vi.size()*2);
auto q = uninitialized_copy(vi.begin(), vi.end(), p);
uninitialized_fill_n(q, vi.size(), 42);