C语言中动态分配数组的大小

C语言中动态分配数组的大小,c,arrays,sizeof,ansi,c89,C,Arrays,Sizeof,Ansi,C89,我知道以前有人问过这个问题,但我的问题更具体, 代码如下: #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);

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

#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 */
}
#包括
#时间函数必须包含include/**/
main()
{
时间t=时间(空);
srand((无符号)t);
int i=rand();
int a[i];
printf(“%d\n”,i);/*输出:18659*/
printf(“%d\n”,大小为a);/*输出:74636*/
}
我使用gcc和-ansi选项编译了这段代码,以限制它只识别ansic。 我知道编译器无法在编译时知道数组的大小,因为它是在运行时随机确定的。 现在我的问题是sizeof返回的值只是一个随机值,还是有意义?

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

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

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


< > <代码> > <代码>(<代码> RAND < /代码>的结果)是随机的,可以认为<>代码> sieOS/<代码>的值在这个意义上也是随机的。

< p>由<代码> SigeOS/<代码>返回的值是一个伪随机值,其含义是:

  • 该值表示VLA
    a
    的大小,以字节为单位
  • 它是随机的,只是因为数组元素的数量是通过调用
    rand
    确定的
系统上的
sizeof(int)
似乎是4,因为
sizeof
返回的数字是数组中元素数的四倍


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

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

根据本规范第6.5.3.4节:

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

因此,
sizeof
返回的大小是VLA的字节大小。在您的示例中,这将是

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


这是无效的C89代码,因为数组长度可变。它在C99+中有效,sizeof在VLAs上显式地执行运行时魔术(提示:74636/18659是什么?)让我们做一个练习-我们尝试将18659乘以4。我们得到了什么?如果您只想要ANSI C,请使用with
-pedantic
选项(with
-Werror
)。(关闭GCC的扩展。)顺便说一句,为了避免UB,这应该是
printf(“%zu\n”,sizeof a)。sizeof返回一个size_t,而不是int。TFM说,“-ansi选项不会导致非ISO程序被无故拒绝。为此,除了-ansi外,还需要-pedantic”。这不是问题的真正答案(sizeof(a)对VLA有效),是吗?@Aconcagua实际上是,因为它意味着sizeof(a)仅在C89中(不使用-Wpedantic选项)的情况下,才在编译时对其进行评估。@MaykelJakson答案中甚至没有提到“sizeof”一词-也没有任何关于在编译/运行时对其进行评估的词语,也没有确认结构是否有效。这可能是正确答案的原因——如果有人回答了“如何仅使用GCC编译ANSI?”这一问题,OP(错误地)认为已经在这样做了。。。