创建有问题的二维阵列(C)
下面的代码是我试图实例化2d数组,但它的实例化不正确: 守则:创建有问题的二维阵列(C),c,multidimensional-array,C,Multidimensional Array,下面的代码是我试图实例化2d数组,但它的实例化不正确: 守则: FILE* kernalFile = fopen(argv[1], "r"); int rKernalSize; fscanf(kernalFile, "%d", &rKernalSize); unsigned int rKernal[rKernalSize][rKernalSize]; 运行代码后立即从断点获取数据: rKernalSize值: Name : rKernalSize
FILE* kernalFile = fopen(argv[1], "r");
int rKernalSize;
fscanf(kernalFile, "%d", &rKernalSize);
unsigned int rKernal[rKernalSize][rKernalSize];
运行代码后立即从断点获取数据:
rKernalSize值:
Name : rKernalSize
Details:3
Default:3
Decimal:3
Hex:0x3
Binary:11
Octal:03
rKernal值:
Name : rKernal
Details:0x7ffffffe0cd0
Default:[0]
Decimal:[0]
Hex:[0]
Binary:[0]
Octal:[0]
或
它应该是rKernal[3][3]
,这是您可以查看的文件。如果需要:
3 -1 1 0 1 0 -1 0 -1 1 3 -1 1 0 1 0 -1 0 -1 1 3 -1 1 0 1 0 -1 0 -1 1
TLDR:
rKernalSize
是正确的(3),但是当我使用rKernal[rKernalSize][rKernalSize]
创建2d数组时,它没有正确实例化!它设置为rKernal[][0]
可能这是默认设置,但应该是rKernal[3][3]
这里的基本问题是,在分配数组时,编译时不知道rKernalSize
。在编译时,int rKernalSize
的值依赖于编译器(除非新的C标准明确将其设置为0;无论如何,0是我打赌的值)。因此,当加载代码时,有一个符号rKernal
表示不包含字节的内存分区的地址
然后你运行程序,用你的scanf读“3”;当您转储结果时,会看到“3”
顺便说一下,这段代码不能在纯C语言中工作——您必须在第一条可执行语句之前进行分配。这将在C++中编译。
现在,如果你想用C来做这样的事情,下面是你需要的:
- 使用scanf读取您的尺码
- 使用
为阵列分配内存,如下所示malloc
- 现在,由于C中的指针数组二元性,可以将其视为数组
x
ari[1][1]=42;//答案是
- 忘记调试器告诉您的内容。在您的代码中,紧接着:
unsigned int rKernal[rKernalSize][rKernalSize];
声明如下:
printf ("%d\n", sizeof(rKernal) / sizeof(unsigned int));
并查看它打印出的内容(希望9
)
在编译时创建的调试信息可能不足以正确确定可变长度数组的大小
举例来说,尽管
gcc
支持可变长度数组,gdb
本身直到2009年底都无法正确处理它们,而且2010年10月的文档中仍然没有提到它们
所以我怀疑这就是问题所在,特别是因为我在上面提供的测试代码按照预期输出了
9
。什么是“它没有正确实例化”的意思?你说“没有正确实例化!”是什么意思?编译时没有对sizeof
进行评估吗?(ed:我猜对于C99中的动态大小数组,它是…)如果我这样做,我会得到以下警告:警告:格式“%d”要求类型为“int”,但参数2的类型为“long unsigned”int@Mark:No.C99 6.5.3.4/2状态如果操作数的类型是可变长度数组类型,则对操作数求值;否则,操作数不会被计算,结果是一个整数常量。
@Jacob:当您运行它时,会发生什么?接下来就是了(忽略警告,这一行是用于调试的临时行:您可以使用正确格式的字符串修复它,但不必使用YAGNI)。底线:您的数组创建正确。事实上,调试器没有足够的信息来计算它在运行时有多大,这是调试器的一个缺陷。确切地说,您必须使用“malloc”并动态分配内存@迈克尔:事实上,你没有。C99引入了可变长度数组的概念,因此该代码在该标准的迭代下是有效的。链接页面中隐藏着代码片段最后,在C99中,您可以使用可变长度数组。:-)GCC做得很好。这些标准从1999年开始就存在了,我想是的,如果你的供应商不支持它,你应该考虑移动:-),而且问题不是关于编译时错误的事实意味着提问者的编译器也支持C99。我不相信你可以将ari
索引为ari[1][1]
如您所述;当您仅分配一块内存时,编译器没有足够的信息将其转换为适当的偏移量。相反,索引需要采用ari[1*rkSize+1]的形式
@paxdiablo:没错。我想我几乎所有的C代码都是按照C90标准编写的。无论如何,谢谢!
unsigned int rKernal[rKernalSize][rKernalSize];
printf ("%d\n", sizeof(rKernal) / sizeof(unsigned int));