我在Windows平台上使用GNU GCC作为编译器在代码块中运行以下程序。在这个程序中我想检查函数中声明的整数是否改变了内存位置。我知道由于编译器优化,它可能会发生,即使它多次声明,它也会为变量保留相同的地址。但我称它为百万次,然后它也需要相同的地址。我也尝试使用volatile关键字,即使使用volatile关键字也显示相同的输出。
#include <iostream>
using namespace std;
int* test (int a, int b)
{
int c=0;
c=c+a+b;
return &c;
}
int main()
{
int* pre;
pre = test(5,9);
int i=0;
for( i=0;i<1000000;i++)
{
int* cur = test(i,i+6);
if(cur!=pre)
{
cout<<"wrong";
}
}
cout<<i;
return 0;
}
答案 0 :(得分:3)
这是一个堆栈。
你把盘子放在那个堆叠的顶部,发现它位于第8位。
然后从顶部取下盘子,然后将其放回那里1000000次。
您现在正在问为什么它始终位于第8位。
我的回答是,为什么不在那里?
显然,这是一个隐喻,并简化了这里发生的事情,要完全理解你可以了解更多关于汇编以及如何执行函数调用,推送参数,使用寄存器,编译器优化等等。板堆栈中发生的事情是你问题的答案:
内存中的作用域变量以堆栈的形式存储。
您的变量只是在内存中的相同位置放置和删除,调用该函数将其推送到堆栈上,并且结束函数范围将其从堆栈中弹出。
答案 1 :(得分:0)
使用更有可能显示不同结果的测试。从代码的不同级别(函数调用深度)调用test()
。从相同级别的代码调用test()
,或者甚至通过优化调用一些不同代码,可能会导致int c
一遍又一遍地占用相同的地址。
为避免未定义的行为问题,此test()
会返回一个整数。
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
intptr_t test(int a, int b) {
int c = 0;
c = c + a + b;
intptr_t ptr = (intptr_t) &c;
return ptr;
}
intptr_t foo(int a, int b) {
// Adjust mask as needed to incur various levels of recursion
if (a&15) return foo(a+1,b); // Call at different levels
return test(a, b);
}
int main() {
intptr_t pre = test(5, 9);
int i = 0;
for (i = 0; i < 1000000; i++) {
intptr_t cur = foo(i, i + 6);
if (cur != pre) {
printf("wrong %d %td != %td\n", i, pre, cur);
break;
}
}
puts("done");
return 0;
}
输出
wrong 0 2673680 != 2673648
done