【发布时间】:2021-04-21 10:28:03
【问题描述】:
我一直在想,是一些与编译器相关的问题还是常规的 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?
【问题讨论】:
-
没有任何改变,也没有编译器问题。您正在打印具有不同值的东西。
-
@WeatherVane:阅读最后一段中的问题。他们不是在询问“可观察的”程序行为。他们在询问他们在调试器中看到的内容。
-
任何此类问题的答案都是:“as-if rule”。 任何事情都是可能的...可能...可能取决于编译器优化设置及其功能。
-
@IntToThe valid 没有任何改变。在第一种情况下,您打印传递给函数的指针变量在堆栈上 的副本的位置。在第二种情况下,您在
main()中打印它的位置。从函数返回后,该位置不再“拥有”。同样,在函数返回后,不能在函数中使用指向局部变量的指针。 -
@AnttiHaapala:不,这不是问题的答案。 OP 不是在问 C 标准说什么或理论上什么是可能的。 OP 使用了调试器,并专门询问他们程序的具体实现中发生了什么。事情确实发生了,他们观察到了,而且是有原因的。
标签: c function pointers memory arguments