【发布时间】:2014-10-29 06:08:37
【问题描述】:
我正在练习 C 编程并尝试创建一个具有固定行但可变列的二维数组。所以,我使用了“指针数组”的概念,即我创建了一个数组,例如 int* b[4]。
这是编写的代码:
#include <stdio.h>
int main(void) {
int* b[4];
int c[]={1,2,3};
int d[]={4,5,6,7,8, 9};
int e[]={10};
int f[]={11, 12, 13};
b[0]=c;
b[1]=d;
b[2]=e;
b[3]=f;
//printing b[0][0] to b[0][2] i.e. c[0] to c[2]
printf("b[0][0]= %d\tb[0][1]=%d\tb[0][2]=%d\n", b[0][0], b[0][1], b[0][2]);
//printing b[1][0] to b[1][5] i.e. d[0] to d[5]
printf("b[1][0]= %d\tb[1][1]=%d\tb[1][2]=%d\tb[1][3]=%d\tb[1][4]=%d\tb[1][5]=%d\n", b[1][0], b[1][1], b[1][2], b[1][3], b[1][4], b[1][5]);
//printing b[2][0] i.e. e[0]
printf("b[2][0]= %d\n", b[2][0]);
//printing b[3][0] to b[3][2] i.e. f[0] to f[2]
printf("b[3][0]= %d\tb[3][1]=%d\tb[3][2]=%d\n", b[3][0], b[3][1], b[3][2]);
return 0;
}
输出如预期:
b[0][0]= 1 b[0][1]=2 b[0][2]=3
b[1][0]= 4 b[1][1]=5 b[1][2]=6 b[1][3]=7 b[1][4]=8 b[1][5]=9
b[2][0]= 10
b[3][0]= 11 b[3][1]=12 b[3][2]=13
所以,我认为内存是这样分配的: 但是,执行此代码时会出现问题:
#include <stdio.h>
int main(void) {
int* b[4];
int c[]={1,2,3};
int d[]={4,5,6,7,8, 9};
int e[]={10};
int f[]={11, 12, 13};
b[0]=c;
b[1]=d;
b[2]=e;
b[3]=f;
int i, j;
for (i=0; i<4; i++)
{
for (j=0; j<7; j++)
{
printf("b[%d][%d]= %d ", i, j, b[i][j]);
}
printf("\n");
}
return 0;
}
而且输出有些不寻常:
b[0][0]= 1 b[0][1]= 2 b[0][2]= 3 b[0][3]= 11 b[0][4]= 12 b[0][5]= 13 b[0][6]= -1079668976
b[1][0]= 4 b[1][1]= 5 b[1][2]= 6 b[1][3]= 7 b[1][4]= 8 b[1][5]= 9 b[1][6]= -1216782128
b[2][0]= 10 b[2][1]= 1 b[2][2]= 2 b[2][3]= 3 b[2][4]= 11 b[2][5]= 12 b[2][6]= 13
b[3][0]= 11 b[3][1]= 12 b[3][2]= 13 b[3][3]= -1079668976 b[3][4]= -1079668936 b[3][5]= -1079668980 b[3][6]= -1079668964
可以观察到 b[0][i] 继续从 b[3][i] 中寻找值,数组 b[2][i] 继续从 b[0][i] 后跟 a[3 寻找值][i],数组 b[3][i] 和 b1[i] 终止。
每次执行此程序时,都会遵循相同的模式。那么,在分配内存的方式上是否还有更多内容,或者这仅仅是巧合?
【问题讨论】:
-
您正在访问内存中超出数组范围的位置,这些位置中存储的任何内容,换句话说就是垃圾,正在被打印出来。
-
当您分配
b[0]=c;时,您认为b[0]中存储的是什么?如果您尝试迭代j > 2会发生什么?您必须有某种方法不尝试读取超出为c, d, e & f分配的空间的末端。由于它们的大小不同,您要么必须将迭代具体限制为每个适当的size,要么有其他方式来表示数据的结束。 -
编译所有警告和调试信息 (
gcc -Wall -Wextra -g)。然后使用调试器 (gdb)。当心undefined behavior