【问题标题】:the size of dynamically allocated array in C [duplicate]C中动态分配数组的大小[重复]
【发布时间】:2017-05-11 12:03:44
【问题描述】:

我知道以前有人问过这个问题,但我的问题更具体, 这是代码:

#include <stdio.h>
#include <time.h>    /* must be included for the time function */

main()
{
    time_t t = time(NULL);
    srand((unsigned) t);

    int i = rand();

    int a[i];

    printf("%d\n", i);        /* ouptut: 18659 */
    printf("%d\n", sizeof a); /* output: 74636 */
}

我使用 gcc 和 -ansi 选项编译了这段代码,以限制它只能识别 ANSI C。 我知道编译器无法在编译时知道数组的大小,因为它是在运行时随机确定的。 现在我的问题是 sizeof 返回的值只是一个随机值,还是有意义的?

【问题讨论】:

  • 由于可变长度数组,这不是有效的 C89 代码。它在 C99+ 中有效,其中 sizeof 显式地在 VLA 上执行运行时魔法(提示:什么是 74636 / 18659?)
  • 让我们做一个练习 - 我们尝试将 18659 乘以 4。我们得到什么?
  • 如果您只需要 ANSI C,请使用 -pedantic 选项(使用 -Werror)。 (关闭 GCC 的扩展。)
  • 顺便说一句,为了避免 UB,这应该是 printf("%zu\n", sizeof a);。 sizeof 返回一个 size_t,而不是 int。
  • TFM 说“-ansi 选项不会导致非 ISO 程序被无偿拒绝。为此,除了 -ansi 之外,还需要 -pedantic”。

标签: c arrays sizeof ansi c89


【解决方案1】:

sizeof 运算符在编译时对大多数操作数进行求值。对于 VLA,它会在运行时进行评估。

来自C standard 的第 6.5.3.4 节:

2 sizeof 运算符产生其操作数的大小(以字节为单位),它可以是表达式或带括号的类型名称。这 大小由操作数的类型决定。结果是一个 整数。 如果操作数的类型是变长数组类型, 计算操作数;否则,不计算操作数,并且 结果是一个整数常量

所以sizeof 返回的大小是VLA 的字节大小。在您的示例中,这将是 i * sizeof(int)

【讨论】:

    【解决方案2】:

    sizeof返回的值是一个有含义的伪随机值:

    • 该值表示VLAa的大小,以字节为单位
    • 仅在数组元素的数量由调用rand 确定的意义上说它是随机的。

    您系统上的sizeof(int) 似乎是4,因为sizeof 返回的数字是数组中元素数量的四倍。

    注意:在 C99 中允许 VLA 的后果之一是 sizeof 不再是纯粹的编译时表达式。当sizeof 运算符的参数是 VLA 时,结果在运行时计算。

    【讨论】:

      【解决方案3】:

      来自gcc manual

      -ansi 选项不会导致非 ISO 程序被无故拒绝。为此,除了 -ansi 之外,还需要 -Wpedantic。

      【讨论】:

      • 这不是问题的真正答案(sizeof(a) 对 VLA 有效),是吗?
      • @Aconcagua 实际上是这样,因为这意味着 sizeof(a) 不再像在 C89 中那样在编译时进行评估(不使用 -Wpedantic 选项)。
      • @MaykelJakson 答案中甚至没有提到“sizeof”这个词——也没有任何关于在编译/运行时评估它的词,也没有确认结构有效。 将是正确答案的原因 - 给出一个答案“如何仅使用 GCC 编译 ANSI?”的问题,OP(错误地)假设已经在做......
      【解决方案4】:

      是sizeof返回的值只是一个随机值,还是有意义的?

      它确实有一个含义,如74636 / 18659 = 4,这显然是您机器上int 的大小。

      所以sizeof(将在运行时而不是编译时计算,因为参数是 VLA),将返回数组 a 的大小(以字节为单位),即 ints 的数量它包含(换句话说,i18659)乘以 int 的大小,即您机器上的 4

      由于irand的结果)是随机的,你可以认为sizeof的值在这个意义上也是随机的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-26
        • 1970-01-01
        • 2011-01-03
        • 2012-09-15
        • 2020-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多