数组声明中的内存分配难题

memory alloc puzzle in array declare

本文关键字:分配 难题 内存 声明 数组      更新时间:2023-10-16

在cpp中,我可以将数组声明为:

char list[20];

它将从内存中分配20,我们可以使用sizeof

来确认它

,也可以声明

char *list = new char[20];

那么这两个声明有什么区别呢?

这两个选项的主要区别在于数组的存储类。这有两个有趣的效果。

  1. 对象在内存中的分配位置
  2. 分配对象的生存期

让我们看看这两个选项并进行比较。

char list[20];

使用此选项,list的存储类取决于它的声明位置。在这两种情况下,list的生命周期在声明它的作用域结束时结束。此时,内存将被自动释放。在此之前,该内存属于list对象,任何指向该内存的指针或引用都保持有效。您还可以将此声明放在类定义中,在这种情况下,list的生命周期将与它绑定的类实例的生命周期一致。

char *list = new char[20];

给定类型char*, list只是指向内存中的字符的指针。如上所述(在初始化中使用new),该字符将是在自由存储上分配的数组(char[20]类型)中的第一个字符。同样,list的生命周期与上面相同。当list超出作用域时,它本身将被销毁(或者它所属的类实例被销毁)。但是,在这种情况下,list只是指针的名称,而不指向数组本身。该数组具有动态存储空间,并将保持分配状态,直到您手动声明应该释放它。可以这样做:

delete[] list;

注意[],这是必需的,因为list是作为数组分配的(使用"array new")。如果您没有delete[]列表,您将泄漏内存,这是不好的,因为这意味着在您的程序终止之前,系统可用于您(和其他进程)的可用内存较少。为了避免记住这一点,您通常应该依赖智能指针,例如shared_ptrunique_ptr

使用动态存储的主要原因是,如果您正在分配(在您的用例中)对于自动存储来说太大的东西,或者您需要对象比声明它的上下文更长寿。缺点是动态内存分配比其他选择要昂贵得多(花费大量时间)。

1) char list[20];的空间将驻留在堆栈中。
2) char *list = new char[20];的空间将位于堆中。然后可以使用'delete'操作符释放它。方法1不能。
当声明方法1的函数返回时,为方法1分配的空间将再次可用。

主要区别在于数组所在的内存:第一个在堆栈上(或在全局变量的数据段中),第二个在堆上。在堆上意味着你对分配的内存负责(你必须在某个地方"删除"它)。