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 命令进行查看局部变量)
通过GDB调试理解指针_初始化

a = 0x1
pon = 0x7ffeefbff960
ppon = 0x0

运行结束退出main之前,a、pon、ppon的值各为:
通过GDB调试理解指针_局部变量_02

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调试理解指针_局部变量_04
在gdb中使用x/1i 0x7ffeefbff948命令查看,得到0x7ffeefbff948: and eax,0xa000050的结果,见下图,
通过GDB调试理解指针_初始化_05
ida中进行查看,可以看到,在这里加了4字节才开始放a值。
通过GDB调试理解指针_gdb_06
但是,这里为什么加4字节,还不知道原因。

update~

关于为什么加4字节,想清楚了,是因为int是4字节,自己的是64位机器,这里多的4字节是因为字节对齐的原因才添加的

0xa00005025 进行分析,拆分为 0xa0x00005025,字节对齐是低位对齐,所以,高位padding 0x00005025,为什么padding 0x00005025,暂时还未找到原因。其内存布局如下所示,为什么是这么布局的,涉及到 大小端机,个人电脑一般都是小端字节序:低位放低地址
通过GDB调试理解指针_局部变量_07

如果最开始将a设置为int a = 0x12345678;,可以得出下面的布局情况,上面的分析得到验证。
通过GDB调试理解指针_局部变量_08