两个数组声明方法c ++之间的区别

时间:2011-07-05 21:59:45

标签: c++ arrays pointers memory-management dynamic-memory-allocation

在c ++中声明数组(并为它们分配内存)的两种方法中的2种

1. int a[3];

2. int *b = new int[3];

我想了解c ++如何以不同的方式对待这两者。

一个。在这两种情况下,我都可以使用以下语法访问数组:a[1]b[1]

湾当我尝试cout<< acout<< b时,都会打印相应数组的第一个元素的地址。

在我看来,a和b都被视为指向数组第一个元素的指针。

℃。但奇怪的是,当我尝试cout << sizeof(a)sizeof(b)时,他们分别打印出不同的值 - 分别为4和12。

我不明白为什么在sizeof(b)的情况下,正在打印整个数组的大小。

5 个答案:

答案 0 :(得分:8)

a是一个数组(类型int [3]
b是一个指针(类型int*

在C ++中,它们完全不同。

sizeof数组是元素的数量乘以每个元素的大小 sizeof指针独立于数组的大小(通常为4或8个字节)。

数组和指针的唯一共同点是数组在几种情况下经常“衰减”到指针。当你打印出它们的价值时,就会发生这种情况。

答案 1 :(得分:3)

正如您所指出的,似乎,好像ab都是指向数组开头的指针。但实际上,只有b是一个指针。 a实际上是一个数组。

在编写(或阅读)代码时,两者之间的差异是微妙的。变量a被视为常规变量(就像intdouble),因为它具有分配给它的自动分配的内存部分。为了比较,假设您已声明int i。变量i是为内存中的某组连续字节赋予的名称,用于保存整数值(计算机上为4个字节)。类似地,a是保存数组的连续字节集的名称(在您的情况下为12个字节)。

相反,b只是指向单个内存位置的指针。在您的情况下,有一个12字节的块,动态分配(通过new int[3])。 b本身是一个自动分配的4字节指针,指向该12字节块中的第一个int值。

所以他们真的是两种不同的东西。这对C ++程序员来说不太清楚。其中一个原因是您可以在两种类型上使用[]运算符。另一个原因是数组在几种情况下隐式退化为指针(例如在函数void Foo(int a[3]);中,a实际上不是数组,而是指向数组开头的指针。但不要被愚弄 - 数组不是指针(正如许多人所声称的那样),指针绝对不是数组。

答案 2 :(得分:0)

在堆栈上分配

1。堆栈上的数组必须具有编译时已知的大小。

2在堆上分配。堆上的数组没有这样的要求。请记住,如果您使用new[]分配,则需要稍后使用delete[]解除分配:

int* b = new int[3];
delete[] b;

答案 3 :(得分:0)

堆栈中的C ++数组有一个限制

int array[10];
sizeof(array) needs to be compile-time constant and
sizeof(array[0])==sizeof(array[1])==...==sizeof(array[9])

堆中的C ++数组只有第二个限制,但不是第一个限制。 (这允许在运行时确定数组大小)

答案 4 :(得分:-1)

堆栈数组(#1)的大小受堆栈限制。 堆数组(#2)的大小受堆的限制(比堆栈大)。

堆栈分配有一些显着的性能优势,请查看此主题以获取更多信息:Which is faster: Stack allocation or Heap allocation