34.动态数组

版权声明:本博客为记录本人学习过程而开,内容大多从网上学习与整理所得,若侵权请告知! https://blog.csdn.net/Fly_as_tadpole/article/details/83063692

new和delete运算符一次只分配/释放一个对象,但是某些应用需要以此为很多对象分配内存的功能。

C++中制定了两种分配/释放多个对象的机制!分别是:new[]/delete[]  和 allocator类。

其中new[]/delete[] 再分配内存的时候就初始化对象;allocator类将内存的分配和对象的初始化分离。


new[]的初始化

int * p = new int[get_size()];
int * q = new int[100];//默认初始化,100个未初始化的int
int * s = new int[100](); //值初始化,100个0
int * m = new int[10]{1,2,3,4,5,6,7,8,9};  //1,2,3,4,5,6,7,8,9,0(0是值初始化)


花括号列表形式的初始化器用来初始化动态数组的开始部分元素。如果初始化器给出的元素大于总的元素数目,则new表达是会出错,不会分配任何内存。当小于总的元素数目的时候,后面的生于元素将会进行值初始化。

delete[] 释放动态数组

typedef int arrT[100];
int * p = new arrT;
delete[] p;

当我们释放一个指向数组的指针的时候,空括号是必须的。因为:它指示编译器此指针指向一个对象数组的第一个元素!如果我们忽略了方括号,其行为是未定义的。

数组的元素的销毁是逆序的。最后一个元素首先被销毁,然后是倒数第二个,以此类推。


智能指针和动态数组

unique_ptr

unique_ptr<int[]> p(new int[100]());  //分配
p.reset() ; //释放

unique_ptr使用下标访问数组中的元素

扫描二维码关注公众号,回复: 3645085 查看本文章
unique_ptr<int[]>p(new int[10]);
for(size_t i = 0;i != 10;i++)
{
    up[i] = i;  //使用下标进行赋值操作
}

shared_ptr  本来是不支持管理一个动态数组的。但是如果我们需要进行这种操作就必须要给它传递一个删除器;

shared_ptr<int>sp(new int[10],[](int* P){delete[] p;});
sp.reset(); // 使用lambda作为删除器,释放数组

shared_ptr  使用get()访问数组元素;

for(size_t i = 0;i != 10;++i)
{
    *(sp.get()+ i) = i;  //通过get()返回内置指针,访问数组元素
}


allocator类    primer p428

其实很简单,将内存的创建+对象的构造分离开来;也就是将 对象的析构+内存的释放分离开来!

内存创建:allocate()   然后返回第一个元素的起始地址

对象的构造:construct()   参数一 位置指针,参数二 对象

对象的析构:destory()  传递指针

内存释放:deallocate()  //传递给deallocate的指针必须是之前某次allocate返回的指针,因此在deallocate之前我们必须要检查该指针是否为空


举个栗子:

#include <iostream>
#include <memory>


using namespace std;

class Animal
{
public:
#if 1        //即使为0,没有默认构造也是可以,
    Animal() : num(0)
    {
        cout << "Animal constructor default" << endl;
    }
#endif
    Animal(int _num) : num(_num)
    {
        cout << "Animal constructor param" << endl;
    }

    ~Animal()
    {
        cout << "Animal destructor" << endl;
    }

    void show()
    {
        cout << this->num << endl;
    }

private:
    int num;
};

int main()
{
    allocator<Animal> alloc;        //1.
    Animal *a = alloc.allocate(5);    //2.

    //3.
    alloc.construct(a, 1);
    alloc.construct(a + 1);
    alloc.construct(a + 2, 3);
    alloc.construct(a + 3);
    alloc.construct(a + 4, 5);

    //4.
    a->show();
    (a + 1)->show();
    (a + 2)->show();
    (a + 3)->show();
    (a + 4)->show();

    //5.
    for (int i = 0; i < 5; i++)
    {
        alloc.destroy(a + i);
    }
    //对象销毁之后还可以继续构建,因为构建和内存的分配是分离的
    //6.
    alloc.deallocate(a, 5);

    cin.get();
    return 0;
}

输出

Animal constructor param
Animal constructor default
Animal constructor param
Animal constructor default
Animal constructor param
1
0
3
0
5
Animal destructor
Animal destructor
Animal destructor
Animal destructor
Animal destructor

猜你喜欢

转载自blog.csdn.net/Fly_as_tadpole/article/details/83063692