我一直在想,这是一些编译器相关的问题或常规的C标准,一些内存可以在没有请求的情况下改变以下代码:
void f(int* p)
{
printf("Value of p: 0x%pn", p);
printf("Address of p: 0x%pn", &p);
}
void scratch()
{
int num = 1; //Dummy value
int* num_p;
num_p = #
f(num_p);
printf("Value of num_p: 0x%pn", num_p);
printf("Address of num_p: 0x%pn", &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%pn", &num_p);
之后地址0x009AF9E8
(包含0x009AFAC8
)改为包含0x009AFABC
?嵌入式输出没有显示它,当我打开内存映射回看指针p时,我检查了它。是否由于最后的printf
而进行了一些编译器调整,并且它可以使用0x009AF9E8
,因为以前的函数不再使用它了?
因为在函数f
返回后,编译器生成的程序将用于参数p
的内存用于其他目的。几乎可以肯定,该内存位于堆栈上,并且程序在调用printf
期间重用了堆栈空间。
当你调用一个函数时,参数的值被复制到参数。因此,当您将num_p
传递给f
时,该值将被复制到本地p
。因为它们是不同的变量(它们是指针的事实在这里是无关紧要的),它们有不同的地址。
当您输入函数时,序言代码为局部变量分配空间。
当从函数返回时,后记代码释放分配的内存。
由于大多数实现使用堆栈存储局部变量,下一个调用的函数将为自己的局部变量重用相同的内存。