Mey*_*sam 63 c++ arrays pointers initialization
这两个声明之间有什么区别吗?
int x[10];
Run Code Online (Sandbox Code Playgroud)
与
int* x = new int[10];
Run Code Online (Sandbox Code Playgroud)
我认为前一个声明(如后一个声明)是一个指针声明,两个变量都可以相同.这是否意味着它们本质上是一样的?
Alo*_*ave 75
#include<iostream>
int y[10];
void doSomething()
{
int x[10];
int *z = new int[10];
//Do something interesting
delete []z;
}
int main()
{
doSomething();
}
Run Code Online (Sandbox Code Playgroud)
int x[10];
Run Code Online (Sandbox Code Playgroud)
- 在堆栈上创建一个大小为10的整数数组.
- 您不必显式删除此内存,因为它会在堆栈展开时消失.
- 其范围仅限于此功能doSomething()
int y[10];
Run Code Online (Sandbox Code Playgroud)
- 在BSS /数据段上创建一个大小为10的整数数组.
- 您不必明确删除此内存.
- 因为它被声明global
它是全球可访问的.
int *z = new int[10];
Run Code Online (Sandbox Code Playgroud)
- 在堆上分配一个大小为10的整数的动态数组,并返回该内存的地址z
.
- 使用后必须明确删除此动态内存.使用:
delete[] z;
Run Code Online (Sandbox Code Playgroud)
唯一相似之处
int x[10];
Run Code Online (Sandbox Code Playgroud)
和
int* x = new int[10];
Run Code Online (Sandbox Code Playgroud)
是否可以在int*
预期的某些上下文中使用:
int* b = x; // Either form of x will work
void foo(int* p) {}
foo(x); // Either form will work
Run Code Online (Sandbox Code Playgroud)
但是,它们不能用于int*
期望a的所有上下文中.特别,
delete [] x; // UB for the first case, necessary for the second case.
Run Code Online (Sandbox Code Playgroud)
其他答案中已经解释了一些核心差异.其他核心差异是:
差异1
sizeof(x) == sizeof(int)*10 // First case
sizeof(x) == sizeof(int*) // Second case.
Run Code Online (Sandbox Code Playgroud)
差异2
类型&x
是int (*)[10]
第一种情况
类型&x
是int**
第二种情况
差异3
给定功能
void foo(int (&arr)[10]) { }
Run Code Online (Sandbox Code Playgroud)
你可以用第一个x
而不是第二个来调用它x
.
foo(x); // OK for first case, not OK for second case.
Run Code Online (Sandbox Code Playgroud)
第一个是int
大小的数组10
.说它在堆栈上创建是错误的.因为标准不保证.它的实现定义.它的存储持续时间可以是静态的或自动的,具体取决于x
是全局变量还是局部变量.
在第二个中,您创建一个类型的指针int*
.不一定是在堆上创建的,标准没有这么说.分配的内存跨越10 * sizeof(int)
字节.为此,您需要通过编写以下内容来释放内存:
delete [] x;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,指针的存储器x
被动态分配并动态地解除分配,因此这些对象被称为具有动态存储持续时间.
根据标准,我们实际上应该区分三种不同类型的数组声明:
int x[10];
void method() {
int y[10];
int *z = new int[10];
delete z;
}
Run Code Online (Sandbox Code Playgroud)
第一个声明int x[10]
使用静态存储持续时间,由cppreference定义为:"当程序开始时分配对象的存储,程序结束时分配对象的存储.只存在一个对象实例.在命名空间范围内声明的所有对象(包括全局命名空间)具有此存储持续时间,以及使用static或extern声明的持续时间."
第二个,int y[10]
使用自动存储持续时间,由cppreference定义为:"对象在封闭代码块的开头分配并在末尾解除分配.所有本地对象都有此存储持续时间,除了那些声明为static,extern或thread_local的存储持续时间".
第三个,int *z = new int[10]
通常称为动态内存分配,实际上是一个两步序列:
正如其他评论中已经提到的,这些类型的声明有其微妙的差异,但最常见的是:
在大多数现代操作系统上:
动态分配的内存应由delete
程序员明确指定,而静态和自动存储变量由"环境"处理
静态和自动存储变量仅限于特定范围,而动态分配的内存没有边界,这意味着,在一个模块中声明的变量可以传递给在同一地址空间中运行的任何其他模块
使用时分配数组时new[]
,大小可以为0
(正如@R Sahu已经指出的那样)&x
和&z
不同的类型:
&x
是 int (*)[10]
&z
是 int **