main()
{static int a[3][4];
int i,j;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
scanf("%d",&a[i][j]);
{for(i=0;i<3;i++)
{ for(j=0;j<4;j++)
printf("%d",a[i][j]);
printf("\n");
}
}
printf("\n");
{for(i=0;i<6;i++)
{ for(j=0;j<2;j++)
printf("%d*",a[i][j]);
printf("\n");
}
}
}
我知道越界不报错 但是能正确输出(后面那个)不知道为什么 拜托大家了
27 个解决方案
#1
for(i=0;i<6;i++)
{
for(j=0;j<2;j++)
printf("%d*",a[i][j]);
printf("\n");
}
这个可以正常输出????? 本来就只有三行四列,当i = 3;是 就是第四行的行地址了,都不知道指向哪里去了
#2
越界访问的行为不可预测,取决于你越界到哪里了(是否还在进程空间中)以及做了什么(读还是写)。
你的例子,你越界读了栈上的空间,读到的值难以预测,虽然未必会crash.
你的例子,你越界读了栈上的空间,读到的值难以预测,虽然未必会crash.
#3
错了,你的程序没有越界,因为 int [3][4]和 int [2][6]的内存布局兼容。
#4
++
你分配了48个字节的内存空间,那种矩形的排列只是为了方便学习而做成的模型,实际上是连续排在一起的,你用{for(i=0;i<6;i++)
{ for(j=0;j<2;j++)
输出,也就是输出那48个字节里的内容
#5
真是这样吗!!
int [3][4]; 那 [4][2] 的数值不是 已到 下一行了么??
#6
那我数组的定义还有什么意义吗?
#7
正常输出,你想一下a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
它的存放位置是连续的 你3 * 4遍历 只是 1,2,3,4 5,6,7,8 9,10,11,12这样遍历出来
而 2 * 6 遍历 是 1,2,3,4,5,6, 7,8,9,10,11,12 这样遍历
始终没有 超过12之后
它的存放位置是连续的 你3 * 4遍历 只是 1,2,3,4 5,6,7,8 9,10,11,12这样遍历出来
而 2 * 6 遍历 是 1,2,3,4,5,6, 7,8,9,10,11,12 这样遍历
始终没有 超过12之后
#8
仔细看下LZ的 代码!!!!!
和下面的代码 有区别么
#include <stdio.h>
int main()
{
int arrya[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
printf("%d\n",arrya[4][2]);
return 0;
}
#9
只是恰巧你越界的位置没有被其他程序使用,所以没有报错。
#10
++
#11
数组的存储是连续的int [3][4]访问的是还是数组本身范围内
#12
下标越界但是你的数据在内存中存放时连续的,可以直接
for(i=0;i<12;i++)
printf("%d",a[i]);
一样可以访问。你把两种方式的地址全部打印出来看下就知道了
for(i=0;i<12;i++)
printf("%d",a[i]);
一样可以访问。你把两种方式的地址全部打印出来看下就知道了
#13
因为 int [3][4]和 int [2][6]的内存布局兼容。
这是什么理论?表示真心没听过。元芳,你怎么看?
元芳曰:“此碎尸案是自杀。”
这是什么理论?表示真心没听过。元芳,你怎么看?
元芳曰:“此碎尸案是自杀。”
#14
就是12个字节嘛
#15
不报错只是巧合,并不代表一直不出问题,那样是危险的
#16
怎么没越界,他程序是int[3][4]变成int[6][2]好不好?(i<6)
#17
不服气啊 为什么我初学到时候 就没有这个问题
发现越界了 就知道错了
发现越界了 就知道错了
#18
给个比较负责任的解释吧
a[3][4]我们可以认为是连续的12个存储单元a相当于a[0][0],其地址我们这样理解即*(a+4*i+j),所以a[6][2],相当于*(a+4*6+2)已经越界了,输出的内容不可预测。
你仔细看C的书应该都有解释。
a[3][4]我们可以认为是连续的12个存储单元a相当于a[0][0],其地址我们这样理解即*(a+4*i+j),所以a[6][2],相当于*(a+4*6+2)已经越界了,输出的内容不可预测。
你仔细看C的书应该都有解释。
#19
C专家编程有讲的貌似~
作案工具,大型绞肉机。。
#20
++
#21
+1
#22
内存布局兼容。。。好亮。
你能告诉我,若a 的地址是0x0000, a + 5 的地址是多少不。
#23
越界会现不可预料的错。
#24
我以前也遇到这个问题 确实没报错 但是你程序要是那么写 按规范说已经错了 毕竟越界
#25
//为了地址计算的方便使用char类型进行计算 char占用一个字节
static char A [3][4] ={1,2,3,4,5,6,7,8,9,10,11,12};
设A的地址为0x0
i < 3 , j < 4
0x0 1 0x1 2 0x2 3 0x3 4 //(0xX Y)0x为地址, Y为地址对应的值
0x4 5 0x5 6 0x6 7 0x7 8
0x8 9 0x9 10 0xA 11 0xB 12
i < 6 , j < 2
0x0 1 0x1 2
0x4 5 0x5 6
0x8 9 0x9 10
0xC 0 0xD 0
0x10 0 0x11 0
0x14 0 0x15 0
因为A的类型为3行4列,每当A[x][y]的时候,相当于去A的A + x * 4 + y的地址区去找值,以此类推,如果是int ,long,double,只要在地址上乘以相应的系数就可以了,
比如int:
i < 3 , j < 4
0x0 1 0x4 2 0x8 3 0xC 4
0x10 5 0x14 6
//相当于
//0x0 1 0x1*4 2 0x2*4 3 0x3*4 4
//0x4*4 5 0x5*4 6
。。。。。。
#26
越界不一定报错,这种行为是未定义
#27
栈里面 虚拟内存已经映射了物理内存 没事儿所以
#1
for(i=0;i<6;i++)
{
for(j=0;j<2;j++)
printf("%d*",a[i][j]);
printf("\n");
}
这个可以正常输出????? 本来就只有三行四列,当i = 3;是 就是第四行的行地址了,都不知道指向哪里去了
#2
越界访问的行为不可预测,取决于你越界到哪里了(是否还在进程空间中)以及做了什么(读还是写)。
你的例子,你越界读了栈上的空间,读到的值难以预测,虽然未必会crash.
你的例子,你越界读了栈上的空间,读到的值难以预测,虽然未必会crash.
#3
错了,你的程序没有越界,因为 int [3][4]和 int [2][6]的内存布局兼容。
#4
++
你分配了48个字节的内存空间,那种矩形的排列只是为了方便学习而做成的模型,实际上是连续排在一起的,你用{for(i=0;i<6;i++)
{ for(j=0;j<2;j++)
输出,也就是输出那48个字节里的内容
#5
真是这样吗!!
int [3][4]; 那 [4][2] 的数值不是 已到 下一行了么??
#6
那我数组的定义还有什么意义吗?
#7
正常输出,你想一下a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
它的存放位置是连续的 你3 * 4遍历 只是 1,2,3,4 5,6,7,8 9,10,11,12这样遍历出来
而 2 * 6 遍历 是 1,2,3,4,5,6, 7,8,9,10,11,12 这样遍历
始终没有 超过12之后
它的存放位置是连续的 你3 * 4遍历 只是 1,2,3,4 5,6,7,8 9,10,11,12这样遍历出来
而 2 * 6 遍历 是 1,2,3,4,5,6, 7,8,9,10,11,12 这样遍历
始终没有 超过12之后
#8
仔细看下LZ的 代码!!!!!
和下面的代码 有区别么
#include <stdio.h>
int main()
{
int arrya[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
printf("%d\n",arrya[4][2]);
return 0;
}
#9
只是恰巧你越界的位置没有被其他程序使用,所以没有报错。
#10
++
#11
数组的存储是连续的int [3][4]访问的是还是数组本身范围内
#12
下标越界但是你的数据在内存中存放时连续的,可以直接
for(i=0;i<12;i++)
printf("%d",a[i]);
一样可以访问。你把两种方式的地址全部打印出来看下就知道了
for(i=0;i<12;i++)
printf("%d",a[i]);
一样可以访问。你把两种方式的地址全部打印出来看下就知道了
#13
因为 int [3][4]和 int [2][6]的内存布局兼容。
这是什么理论?表示真心没听过。元芳,你怎么看?
元芳曰:“此碎尸案是自杀。”
这是什么理论?表示真心没听过。元芳,你怎么看?
元芳曰:“此碎尸案是自杀。”
#14
就是12个字节嘛
#15
不报错只是巧合,并不代表一直不出问题,那样是危险的
#16
怎么没越界,他程序是int[3][4]变成int[6][2]好不好?(i<6)
#17
不服气啊 为什么我初学到时候 就没有这个问题
发现越界了 就知道错了
发现越界了 就知道错了
#18
给个比较负责任的解释吧
a[3][4]我们可以认为是连续的12个存储单元a相当于a[0][0],其地址我们这样理解即*(a+4*i+j),所以a[6][2],相当于*(a+4*6+2)已经越界了,输出的内容不可预测。
你仔细看C的书应该都有解释。
a[3][4]我们可以认为是连续的12个存储单元a相当于a[0][0],其地址我们这样理解即*(a+4*i+j),所以a[6][2],相当于*(a+4*6+2)已经越界了,输出的内容不可预测。
你仔细看C的书应该都有解释。
#19
C专家编程有讲的貌似~
作案工具,大型绞肉机。。
#20
++
#21
+1
#22
内存布局兼容。。。好亮。
你能告诉我,若a 的地址是0x0000, a + 5 的地址是多少不。
#23
越界会现不可预料的错。
#24
我以前也遇到这个问题 确实没报错 但是你程序要是那么写 按规范说已经错了 毕竟越界
#25
//为了地址计算的方便使用char类型进行计算 char占用一个字节
static char A [3][4] ={1,2,3,4,5,6,7,8,9,10,11,12};
设A的地址为0x0
i < 3 , j < 4
0x0 1 0x1 2 0x2 3 0x3 4 //(0xX Y)0x为地址, Y为地址对应的值
0x4 5 0x5 6 0x6 7 0x7 8
0x8 9 0x9 10 0xA 11 0xB 12
i < 6 , j < 2
0x0 1 0x1 2
0x4 5 0x5 6
0x8 9 0x9 10
0xC 0 0xD 0
0x10 0 0x11 0
0x14 0 0x15 0
因为A的类型为3行4列,每当A[x][y]的时候,相当于去A的A + x * 4 + y的地址区去找值,以此类推,如果是int ,long,double,只要在地址上乘以相应的系数就可以了,
比如int:
i < 3 , j < 4
0x0 1 0x4 2 0x8 3 0xC 4
0x10 5 0x14 6
//相当于
//0x0 1 0x1*4 2 0x2*4 3 0x3*4 4
//0x4*4 5 0x5*4 6
。。。。。。
#26
越界不一定报错,这种行为是未定义
#27
栈里面 虚拟内存已经映射了物理内存 没事儿所以