在 cpp 中,我可以将一个数组声明为:
char list[20];
它将从内存中分配 20,我们可以使用 sizeof 确认它
我们也可以声明
char *list = new char[20];
那么两者声明有什么区别?
在 cpp 中,我可以将一个数组声明为:
char list[20];
它将从内存中分配 20,我们可以使用 sizeof 确认它
我们也可以声明
char *list = new char[20];
那么两者声明有什么区别?
主要区别在于数组所在的内存:第一个在堆栈上(或在全局数据段中),第二个在堆上。在堆上意味着您负责分配的内存(您必须在某处“删除”它)。
1) for 的空间char list[20];
将存在于堆栈中。
2) for 的空间char *list = new char[20];
将存在于堆中。然后可以使用“删除”操作符释放它。方法1不能。
当声明它的函数返回时,为方法 1 分配的空间将再次可用。
这两个选项之间的主要区别在于阵列的存储类。这有两个有趣的效果。
让我们看看这两个选项并进行比较。
char list[20];
使用此选项,存储类list
取决于它的声明位置。在任何一种情况下,它的生命周期都list
将在声明它的范围结束时结束。此时,内存将被自动释放。在此之前,内存属于该list
对象,并且对该内存的任何指针或引用都保持有效。您也可以将此声明放在类定义中,在这种情况下,它的生命周期list
将与其绑定的类实例的生命周期一致。
char *list = new char[20];
给定 type char*
,list
只是一个指向内存中字符的指针。如前所述(在初始化中使用),该字符将是在空闲存储上分配new
的数组(类型为 )中的第一个字符。char[20]
同样,生命周期与list
上述相同。list
当它超出范围(或者它所属的类实例被销毁)时,它本身将被销毁。但是,在这种情况下list
只是指针的名称,并不引用数组本身。该数组具有动态存储,并且将保持分配状态,直到您手动声明它应该被释放。这可以这样做:
delete[] list;
注意[]
, 这是必需的,因为list
它被分配为一个数组(使用“array new”)。如果您没有delete[]
列出该列表,您将泄漏内存,这很糟糕,因为这意味着系统对您(和其他进程)可用的内存较少,直到您的程序终止。为了避免记住这一点,您通常应该依赖智能指针,例如shared_ptr
和unique_ptr
。
使用动态存储的主要原因是,如果您分配的东西(在您的用例中)对于自动存储来说太大了,或者您需要对象比声明它的上下文更长寿。缺点是动态内存分配比其他替代方案更昂贵(需要很多时间)。