这是main.c:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int size = atoi(argv[1]);
int int_array[10][10];
int *before = NULL;
int *val[size];
int *after = NULL;
printf("before:%p, after:%p, sizeof val:%lu\n", before, after, sizeof val);
int i = 0;
/*for (; i < 10; i++) {
val[i] = int_array[i];
}*/
val[0] = int_array[0];
val[1] = int_array[3];
printf("int_array:%p, int_array[0]:%p, int_array[1]:%p, int_array[2]:%p, int_array[3]:%p\n", int_array, int_array[0], int_array[1], int_array[2], int_array[3]);
printf("val:%p, val[0]:%p, val[1]:%p, val[2]:%p, val[3]:%p\n", val, val[0], val[1], val[2], val[3]);
printf("before:%p, after:%p\n", before, after);
return 0;
}
[root@localhost test]# ./test 3
before:(nil), after:(nil), sizeof val:24
int_array:0x7ffeadc69470, int_array[0]:0x7ffeadc69470, int_array[1]:0x7ffeadc69498, int_array[2]:0x7ffeadc694c0, int_array[3]:0x7ffeadc694e8
val:0x7ffeadc69440, val[0]:0x7ffeadc69470, val[1]:0x7ffeadc694e8, val[2]:0x3, val[3]:0x4005ba
before:(nil), after:(nil)
[root@localhost test]# ./test 6
before:(nil), after:(nil), sizeof val:48
int_array:0x7ffcd30f1f50, int_array[0]:0x7ffcd30f1f50, int_array[1]:0x7ffcd30f1f78, int_array[2]:0x7ffcd30f1fa0, int_array[3]:0x7ffcd30f1fc8
val:0x7ffcd30f1f00, val[0]:0x7ffcd30f1f50, val[1]:0x7ffcd30f1fc8, val[2]:0x7ffcd30f2220, val[3]:(nil)
before:(nil), after:(nil)
编译代码:gcc -o test main.c,然后在./test 3和./test 6上面得到输出。
因此,确定sizeof()
时不是编译时间而是运行时间?
答案 0 :(得分:8)
可变大小的2D数组声明是否错误?
在C ++中,所有数组变量的大小必须为编译时间常数。 size
不是编译时间常数,因此int *val[size];
在C ++中格式错误。
答案 1 :(得分:0)
对于VLA,是的,sizeof
的结果是在运行时计算的:
6.5.3.4sizeof
和_Alignof
运算符
...
2sizeof
运算符产生其操作数的大小(以字节为单位),可能是 表达式或类型的括号名称。大小由以下类型决定 操作数。结果是一个整数。 如果操作数的类型是可变长度数组 类型,则对操作数求值; 否则,不对操作数求值,结果为 整数常量。
已添加重点。
这很有道理,因为直到运行时才确定VLA的大小。
我不知道您要使用before
和after
完成什么工作-如果您要查看val
占用了什么地址,那不是做到的方式。首先,您需要打印&before
和&after
的值,但是即使如此,也无法保证对象以声明时的顺序排列在内存中。也不能保证VLA与其他auto
变量是从同一内存区域分配的(通常是,但这不是必需的)。
答案 2 :(得分:0)
感谢John和Blaze,是的,它是VALs
(可变数组长度),GNU C编译器(gcc)支持它作为C99的扩展。因此,很多事情取决于编译器。
在Wikipedia中可以找到更多的知识:
分配