34.动态数组

本文深入探讨了C++中动态内存管理的多种方式,包括new/delete、new[]/delete[]及allocator类的使用,对比了它们的特点与适用场景,并详细介绍了智能指针在管理动态数组时的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 arrT[100] int ;
int * p = new arrT;
delete[] p;

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

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


智能指针和动态数组

unique_ptr

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

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

unique_ptr<int[]>up(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

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值