最近在复习C++相关内容,对指针始终理解不到位,对指针间的数据还是持有怀疑太多,所以借助GDB进行调试,以加深自己对指针的理解。
源代码:
#include <iostream>
int main()
{
int a = 10;
int* pon = &a;
//pon是一个int型,其值为 a的地址,即 pon == &a
printf("pon = %X, *pon = %d, &a = %X, &pon = %X\n", pon, *pon, &a, &pon);
int** ppon = &pon;
printf("ppon = %X, *ppon = %X, **ppon = %d, &ppon = %X\n", ppon, *ppon, **ppon, &ppon);
}
编译上面的代码之后进行调试。
在初始化之前,a、pon、ppon的值各为:(可以使用info locals
命令进行查看局部变量)
a = 0x1
pon = 0x7ffeefbff960
ppon = 0x0
运行结束退出main之前,a、pon、ppon的值各为:
a = 0xa
pon = 0x7ffeefbff94c
ppon = 0x7ffeefbff940
通过上面的输出结果,以及printf输出的值:
pon = EFBFF94C, *pon = 10, &a = EFBFF94C, &pon = EFBFF940
ppon = EFBFF940, *ppon = EFBFF94C, **ppon = 10, &ppon = EFBFF938
通过这里可以看出如下的关系:
对上图的解释:
ppon 是一个 指向指针的指针,指针指向pon;pon是一个指针,指向a;int **ppon = &pon;
等价于int **ppon; *pon = pon;
其他:
上图中,可以看到 ppon和pon地址是挨着的,差了8位是因为我的是64位机器,但是:pon和a之间差了12,本来只应该差8的,但这里多出了4字节,在gdb中可以看到0x7ffeefbff948 存放的是 ‘%P’,但是怎么来得,没有分析出来。
在gdb中使用x/1i 0x7ffeefbff948
命令查看,得到0x7ffeefbff948: and eax,0xa000050
的结果,见下图,
ida中进行查看,可以看到,在这里加了4字节才开始放a值。
但是,这里为什么加4字节,还不知道原因。
update~
关于为什么加4字节,想清楚了,是因为int是4字节,自己的是64位机器,这里多的4字节是因为字节对齐的原因才添加的。
对 0xa00005025
进行分析,拆分为 0xa
和 0x00005025
,字节对齐是低位对齐,所以,高位padding 0x00005025
,为什么padding 0x00005025
,暂时还未找到原因。其内存布局如下所示,为什么是这么布局的,涉及到 大小端机,个人电脑一般都是小端字节序:低位放低地址。
如果最开始将a设置为int a = 0x12345678;
,可以得出下面的布局情况,上面的分析得到验证。