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

关于C语言数组下标问题怎么回事哈啊?

关于C语言数组下标问题怎么回事哈啊?

回首忆惘然 2019-10-16 09:37:41
intarr[]={0,12,1,23,65,1,3,99,78};printf("%d\n",arr[-1]);for(inti=0;i
查看完整描述

2 回答

?
SMILET

TA贡献1796条经验 获得超4个赞

越界了,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-10-16
?
莫回无

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

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

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信