【问题标题】:C programming register values?C编程寄存器值?
【发布时间】:2015-02-16 17:16:01
【问题描述】:

在下面的程序中,第二个 printf 语句打印的内存位置和值与第一个 printf 语句相同。为什么?

是不是因为调用第二个 printf 语句时寄存器的值没有改变? y 变量从未初始化,所以当 printf 被调用时,它只会在堆栈上找到 'x'?

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

void foo1( int xval ) {

    int x;
    x = xval;

    /* print the address and value of x here */
    printf("x\t | %#x\t\t| %d\n", &x, x);
}

void foo2( int dummy ) {

    int y;

    /* print the address and value of y here */
    printf("y\t | %#x\t\t| %d\n", &y, y);
}


int main() {

    printf("Variable | Memory Location\t| Value\n");
    foo1(7);
    foo2(11);

    return( 0 );
}

输出:

Variable | Memory Location  | Value
x    | 0xe6ffa3cc       | 7
y    | 0xe6ffa3cc       | 7

【问题讨论】:

  • 为什么不打印相同的地址?而且您不能对未定义的行为抱有任何期望,但在您的情况下,您可能是对的。
  • 读取未初始化的值是未定义的行为,因此您不能期望任何特定的输出。 (顺便说一句,C 没有指定具有非重叠生命周期的两个对象必须驻留在不同的地址。C 是硬件之上的高级抽象。如果要手动指定和检查内存位置,请使用汇编,并且不是 C.)
  • 因为,我认为 foo2 很可能使用与 foo1 相同的堆栈帧,并且它们都使用相同数量的相同数据,导致相同的地址。
  • @Linuxios 可能接近正确,除了它不是相同的堆栈帧,而是每个堆栈帧和/或局部变量的堆栈空间相同。不过,Croissant 说得对:y 的内容是未定义的,它的地址也是如此;因此,这种行为可能会随着程序、编译器、平台甚至某处的随机位的简单更改而改变。 (好吧,好吧,最后一个在推动它,但你明白了。)
  • @JoeSewell:对不起,对。不是同一个堆栈帧,只是在堆栈中占用相同的内存区域,因为它们的堆栈帧(至少对于我能想到的任何理智的编译器)是相同的大小。

标签: c assembly cpu-registers


【解决方案1】:

foo1() 中,您正在分配值x,它位于堆栈上地址0xe6ffa3cc 下。这意味着这个特定的内存区域被初始化为值 7。

foo2 内部,您正在打印未初始化的值y。这个值也位于堆栈上,我敢打赌它意外地位于与x 之前相同的地址下(您正在调用具有相同签名的函数,这可能会导致相同的堆栈“布局”)。由于y 未初始化,因此它包含上一次调用的“垃圾”,即 7。

此行为未定义。在不同的平台(操作系统、硬件)上,它可能会给你不同的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-25
    • 2019-12-26
    • 2012-01-02
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 2016-11-11
    • 1970-01-01
    相关资源
    最近更新 更多