数组声明中的内存分配难题
memory alloc puzzle in array declare
在cpp中,我可以将数组声明为:
char list[20];
它将从内存中分配20,我们可以使用sizeof
来确认它,也可以声明
char *list = new char[20];
那么这两个声明有什么区别呢?
这两个选项的主要区别在于数组的存储类。这有两个有趣的效果。
- 对象在内存中的分配位置
- 分配对象的生存期
让我们看看这两个选项并进行比较。
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_ptr
和unique_ptr
。
使用动态存储的主要原因是,如果您正在分配(在您的用例中)对于自动存储来说太大的东西,或者您需要对象比声明它的上下文更长寿。缺点是动态内存分配比其他选择要昂贵得多(花费大量时间)。
1) char list[20];
的空间将驻留在堆栈中。
2) char *list = new char[20];
的空间将位于堆中。然后可以使用'delete'操作符释放它。方法1不能。
当声明方法1的函数返回时,为方法1分配的空间将再次可用。
主要区别在于数组所在的内存:第一个在堆栈上(或在全局变量的数据段中),第二个在堆上。在堆上意味着你对分配的内存负责(你必须在某个地方"删除"它)。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 数组声明中的内存分配难题