为了账号安全,请及时绑定邮箱和手机立即绑定

关于C语言数组下标问题

关于C语言数组下标问题

Cats萌萌 2019-11-03 15:49:18
intarr[]={0,12,1,23,65,1,3,99,78};printf("%d\n",arr[-1]);for(inti=0;i
查看完整描述

2 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

越界了,undefinedbehavior。你这个代码中,都是在栈上分配的,栈是高位往低位扩张,一开始栈的布局是这样的a9a8a7a6a5a4a3a2a1a0每次loop,会在低位申请然后又释放i,栈的布局:a9a8a7a6a5a4a3a2a1a0i这种情况下arr[-1]就会一直输出i
这里有个小问题,我在wsl上试着是4个字节,而在mac是两个字节,但mac上的整型也是4个字节,不知道为什么这儿就变成两个字节了)
我猜你计算2和4是代码里面输出两个地址相减的值的。你的wsl应该是默认编译出32位的程序,直接减得到4没问题。mac上编译出来的是64位的,你直接减,然后输出的时候应该是溢出了,得到个2,你试试先把地址转longlong,用%lld输出试试,会得到一个8,而不是2或者4。这是因为分配空间的时候还会做内存对齐,分配i的时候会再跳过高位的4个字节再去分配i,保证i的地址也是8的倍数,所以实际地址差是8,64位的程序堆结构大概如下:0a8a7a6a5a4a3a2a1a00i
贴一个gdb的输出
//code
inta[]={1,2,3,4,5,6,7,8,9};
inti=2;
//gdb
p&i
(int*)$1=0x00007ffeefbffdc8
x/11dw0x00007ffeefbffdc8
0x7ffeefbffdc8:2
0x7ffeefbffdcc:0
0x7ffeefbffdd0:1
0x7ffeefbffdd4:2
0x7ffeefbffdd8:3
0x7ffeefbffddc:4
0x7ffeefbffde0:5
0x7ffeefbffde4:6
0x7ffeefbffde8:7
0x7ffeefbffdec:8
0x7ffeefbffdf0:9
                            
查看完整回答
反对 回复 2019-11-03
?
眼眸繁星

TA贡献1873条经验 获得超9个赞

下标越界。
向后越界(比0还小)指向低位指针地址,向前越界(比数组长度还大)指向高位指针地址。如果指向的地址没被使用,也就是个野地址,那么结果就是是随机的,无意义。
这个代码段里第一个arr[-1]指向什么还得看上下文,不同的上下文结果不一定都是32689;for循环里的arr[-1]指向i了。
这种黑魔法少用,基本没有可读性。
                            
查看完整回答
反对 回复 2019-11-03
  • 2 回答
  • 0 关注
  • 185 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号