首页 > 解决方案 > 使 7 年前的印刷品与现在兼容

问题描述

我正在阅读 The Art Of Exploitation 这本书,有一个名为的程序memory_segments.c向我们演示了内存段、堆、堆栈等是如何工作的。但是当我尝试编译该程序时,似乎打印是'不更兼容现在。我使用gcc10.2.0 来编译我的 C 代码。

#include <stdio.h>
#include <stdlib.h>

int global_initialized_var = 5;

int main() 
{
   printf("global_initialized_var is at address 0x%08x\n", &global_initialized_var);
   // ... more prints, removed just to make code shorter

   return 0;
}  
// warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’

本书输出的作者:

...
global_initialized_var is at address 0x080497ec
...

什么是替代品0x%08x?为什么0x%08x不再工作?

标签: cprintf

解决方案


  1. %x打印整数值而不是指针。这是未定义的行为。要打印指针,请使用printf("%p", (void *)pointer);
  2. 转换指针时应使用的整数类型是uintptr_tintptr_t。对于指针之间的差异ptrdiff_t
  3. 要打印uintptr_t还是intptr_t需要使用PRIdPTR PRIiPTR PRIoPTR PRIuPTR PRIxPTR PRIXPTRprintf 格式。例子:
uintptr_t p = SOME_VALUE;
printf("UINTPTR_T printed as hex: %" PRIxPTR "\n", p);

推荐阅读