【问题标题】:difference between two array declaration methods c++两种数组声明方法c ++之间的区别
【发布时间】:2011-09-29 04:22:03
【问题描述】:

在 C++ 中声明数组(并为它们分配内存)的可能有多种方法中的 2 种

1. int a[3];

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

我想了解 c++ 如何区别对待这两者。

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

b.当我尝试cout<< acout<< b 时,都打印各自数组的第一个元素的地址。

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

c。但奇怪的是,当我尝试执行 cout << sizeof(a)sizeof(b) 时,它们分别打印不同的值 - 4 和 12。

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

【问题讨论】:

  • 静态分配 vs 动态分配,一个在栈上,一个在堆上
  • @Kshitij:这是自动分配,不是静态的。静态是加载时分配(用于全局对象)。
  • @Kerrek SB - 你能详细说明自动分配和静态分配之间的含义和区别吗?我尝试使用谷歌搜索,但没有发现任何好东西。

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


【解决方案1】:

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

在 C++ 中,它们是完全不同的东西。

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

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

【讨论】:

  • 按照惯例,p[n] 被视为*(p + n),因此您也可以将指针视为数组。
  • -1: b not 是指向数组的指针。 b 是一个指向 int 的指针。 int (*b)[N] 是指向数组的指针
  • @Armen:两者兼而有之。它的类型是int*,但它清楚地指向一个数组,因为您必须使用delete[]。我会澄清的。
  • @Peter Alexander:我删除了我的反对票,我知道你的意思是好的,但从术语上讲,“指向数组的指针”仍然不正确,恕我直言
  • @Dev Kanchen:是的,这是 OP 中的一个错字。
【解决方案2】:

如您所述,似乎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 实际上不是数组,而是指向数组开头的指针)。但不要上当——数组不是指针(正如许多人声称的那样),指针绝对不是数组。

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • 1 不一定在堆栈上。如果它是一个类的成员并且该类的一个实例分配在堆上,那么该数组将在堆中。不要将“堆栈”与自动存储混淆。
    • 1) 有点正确,但是像alloca 或可变长度数组这样的东西也可以有效地让您分配可变长度的自动对象。
    • 好点,虽然我只是假设在他的例子中它在堆栈上。
    • 第一个示例也可以是全局的,因此既不在堆栈上也不在堆上,而是静态的。
    【解决方案4】:

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

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

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

    【讨论】:

    • 只是澄清一下:动态分配数组的大小必须在实际分配之前确定,并且可能还会存储在变量中。没有办法查看数组本身并推断其大小。
    猜你喜欢
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多