为什么在没有显式修改的情况下修改内存

Why memory is being modified without explicit modification

我一直在想,在下面的代码中,一些内存可以在没有请求的情况下被更改,是一些编译器相关的问题还是常规的 C 标准:

void f(int* p)
{
    printf("Value of p: 0x%p\n", p);
    printf("Address of p: 0x%p\n", &p);
}

void scratch()
{
    int num = 1; //Dummy value
    int* num_p;
    num_p = #

    f(num_p);

    printf("Value of num_p: 0x%p\n", num_p);
    printf("Address of num_p: 0x%p\n", &num_p);
}

我的输出是:

Value of p: 0x009AFAC8
Address of p: 0x009AF9E8
Value of num_p: 0x009AFAC8
Address of num_p: 0x009AFABC

我的问题是:为什么在 printf("Address of num_p: 0x%p\n", &num_p); 之后,地址 0x009AF9E8(包含 0x009AFAC8)变为包含 0x009AFABC?嵌入式输出没有显示它,我打开内存映射回头看指针p时检查了它。是不是因为最后的printf,编译器做了一些调整,可以用0x009AF9E8,因为之前的函数不用了?

当您调用一个函数时,参数的值会复制到参数中。所以当你将num_p传递给f时,值被复制到本地p。由于它们是不同的变量(它们是指针的事实在这里无关紧要),它们具有不同的地址。

因为在函数f返回后,编译器生成的程序将其用于参数p的内存重新用于另一个目的。几乎可以肯定,该内存在堆栈上,并且程序在调用 printf.

期间重用了堆栈 space

当您进入函数时,序言代码会为局部变量分配 space。

当您从函数中 return 时,尾声代码会释放分配的内存。

由于大多数实现将堆栈用于局部变量,下一个调用的函数将为其自己的局部变量重用相同的内存。