printf 后将变量内容转换为指针结果为 NULL

标签 c pointers casting printf low-level

我尝试实现以下目标:我有一个指针p指向一个再次保存地址的地址(该地址也是一个有效地址)。现在我想要另一个指针pp指向p的内容地址。所以我正在执行以下操作:

// Retrieve the start address
unsigned long long *p = getInitialAddress();

// Let pp point to next address
unsigned long long *pp = (unsigned long long*)(*p);

// Print address
printf("0x%llx %p\n", *p, pp);

这将打印例如:0x7fffedc47a70 0x7fffedc47a70,这是所需的结果。

但是,将另一个 printf 放入代码中,如下所示:

// Retrieve the start address
unsigned long long *p = getInitialAddress();

// Print
printf("%p 0x%llx\n", p, *p);

// Let pp point to next address
unsigned long long *pp = (unsigned long long*)(*p);

// Print address
printf("0x%llx %p\n", *p, pp);

导致:

0x7fffacea3660 0x7fffacea3680
0x0 (nil)

这不是正确的结果,因为它应该是

0x7fffacea3660 0x7fffacea3680
0x7fffacea3680 0x7fffacea3680

那么 printf 是否改变了指针中的某些内容或者出了什么问题?

编辑:完整代码

unsigned long long* readRBP();

int main(void) {
    // Retrieve the start address
    unsigned long long *p = readRBP();

    // Print
    printf("%p 0x%llx\n", p, *p);

    // Let pp point to next address
    unsigned long long *pp = (unsigned long long*)(*p);

    // Print address
    printf("0x%llx %p\n", *p, pp);

    return 0;
}

unsigned long long* readRBP() {
    unsigned long long rbp;
    __asm__ volatile("mov %%rbp, $0" : "=r"(rbp));
    return (unsigned long long*)rbp;
}

这将获取 rbp(堆栈基指针)。这个指针的内容是指向下一个rbp的指针等等。 这个 rbp 来自 readRBP() 本身,下一个 rbp 属于 main,main 之后的下一个 rbp 是 0x0,岛。 e.一开始。

最佳答案

readRBP 返回的值是 readRBP 函数的基指针。然后,您调用 printf 创建自己的堆栈帧。该堆栈帧会删除 *p 处的数据。

要看到这一点,您就可以这样编写代码:

int main(void) {
    // Retrieve the start address
    unsigned long long *p = readRBP();
    unsigned long long pContents = *p
    unsigned long long *pp = (unsigned long long*)(*p);

    // Print
    printf("%p 0x%llx %p\n", p, pContents, pp);

    return 0;
}

换句话说,您将所有信息收集到 main 的堆栈帧中,然后再通过调用 printf 来处理它。

关于printf 后将变量内容转换为指针结果为 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10154630/

相关文章:

swift - 快速类型转换后对数组中的对象执行变异函数

c - gcc 内联汇编错误 "operand type mismatch for mov"

c - 为什么在 C 中遍历单链表时 NULL 指针检查不起作用?

c - 如果我的指针越过数组边界会怎样?

c++ - 将整数文字赋给指针?

sql-server - SQL Server 2005 中的平均时间值

java - 对通用类型的数组进行排序

c - 在 C 中访问 union 体成员的成员

c - 尝试从用户库访问函数时出现段错误

c - 如何在 ubuntu 中计算 C 程序的运行时间