void指针指向字符串打印地址异常,如何获取正确地址?
问题解答
地址差异与重复相同地址的原因
虚拟内存 vs ELF静态偏移
printf打印的是进程虚拟地址空间中的运行时地址,你在ELF文件中看到的是静态偏移(节内偏移或文件偏移)。现代操作系统依赖虚拟内存机制,程序加载时会把ELF的各段(比如存储字符串字面量的.rodata只读数据段)映射到进程专属的虚拟地址空间,映射的基地址由操作系统分配(可能受ASLR地址空间布局随机化影响),因此运行时虚拟地址和ELF文件里的静态偏移必然不同。字符串字面量的合并优化
两次定义指针指向同一个"TestString"却得到相同地址,是正常的编译器优化行为——编译器会把内容完全一致的字符串字面量合并到.rodata段的同一位置(字符串池优化),以此节省内存。这恰恰说明指针指向的是正确的运行时地址,而非错误地址。
你打印的到底是什么?
printf("%p", str)输出的就是"TestString"在当前进程虚拟地址空间中的实际运行时地址,这个地址是程序运行时操作系统分配的虚拟地址,也是程序访问该字符串时真正使用的地址,完全正确。
如何获取你需要的“正确地址”
分两种场景:
- 如果需要程序运行时实际访问的地址:你当前的代码打印的就是正确结果,直接用
%p输出即可。 - 如果需要ELF文件中的静态偏移地址:
- 用
readelf -x .rodata 你的程序文件名查看只读数据段内容,找到"TestString"在.rodata段内的偏移; - 用
readelf -S 你的程序文件名查看.rodata段在ELF文件中的起始偏移; - 将两个偏移相加,得到的就是该字符串在ELF文件中的静态偏移地址(注意这仅代表文件内的位置,不是运行时地址)。
- 用
内容的提问来源于stack exchange,提问作者Cool Camel
相关产品推荐
相关产品推荐

