知道为什么自己的结果和视频不一样了。视频里应该是有问题的吧?

来源:5-1 数组申明的内存排列

白腿小隼熊猫鸟

2019-02-24 15:43

自己的输出结果,跟很多底下评论的同学一样,跟视频里的是不一样的:

$ ./a.out 
*p = 3
*p = 1
*p = 2
*p = 1384734840
*p = 32766
*p = 5
----------------------------------------------------
p[0] = 3
p[1] = 1
p[2] = 2
p[3] = 1384734828
p[4] = 32766
p[5] = 5


在gdb里,输出了一下所有变量的地址,知道了原因是「指针p」本身占据了整型变量之间的地址位,所以输出的结果和视频里不一样,不是连续的,而是出现了随机数。在64位操作系统里,指针p本身占据8个字节。我这里的gdb的结果如下:

(gdb) p a
$1 = 3
(gdb) p &a
$2 = (int *) 0x7fffffffdabc
(gdb) p b
$3 = 2
(gdb) p &b
$4 = (int *) 0x7fffffffdac4
(gdb) p  i
$5 = 0
(gdb) p &i
$6 = (int *) 0x7fffffffdac0
(gdb) p p
$7 = (int *) 0x7fffffffdac0
(gdb) p &p
$8 = (int **) 0x7fffffffdac8
(gdb) p array[0]
$9 = 5
(gdb) p &array[0]
$10 = (int *) 0x7fffffffdad0
(gdb) p array[1]
$11 = 50
(gdb) p &array[1]
$12 = (int *) 0x7fffffffdad4
(gdb) p array[2]
$13 = 500
(gdb) p &array[2]
$14 = (int *) 0x7fffffffdad8

所以,再回头去看程序的输出,就可以知道:

第一行输出的p[0]=3,这是变量a的值,没有疑问;
第二行输出的p[1]=1,这是变量i的值,没有疑问;
第三行输出的p[2]=2,这是变量b的值,没有疑问;
第四行输出的p[3]=1384734840,这是指针变量p本身所在位置的前4个字节的值,因为没有被初始化过,所以是系统随机给的数;
第五行输出的p[4]=32766,这是指针变量p本身所在位置的后4个字节的值,因为没有被初始化过,所以是系统随机给的数;
第六行输出的p[5]=5,这是数组array[0]的值,没有疑问。

综上所述,编译器编译程序时,正如之前老师讲过的,会自动优化内存分配,把同类型的变量分配到一段连续的内存里,所以这里就把所有的整型变量都挨个分配在一起了,只不过顺序并不是我们想象的那样从a到b到array到i到指针p本身,而是把变量i和指针p本身插到了a、b、array的中间,所以程序代码从a的地址开始顺序输出的时候,没有得到期望的结果。


写回答 关注

1回答

  • 寒冰兔子
    2019-06-18 22:14:07

    这个要看编译器的,老师讲的内容,其实数组已经越界,在实际使用中不会出现的,如果实际应用中出现说明程序有问题。

Linux C语言指针与内存

指针-C语言的核心,代领大家对c语言有更加深刻的理解

116627 学习 · 254 问题

查看课程

相似问题