有人可以帮我理解这些程序的输出。
int* fun1();
void fun2();
int main()
{
int *p=fun1();
fun2();
printf("%d\n",*p);
return 0;
}
int* fun1()
{
int i=10;
return &i;
}
void fun2()
{
int a=100;
printf("%d\n",a);
}
Windows上为100 100,Linux上为100 10。 Windows输出我能够证明由于局部变量在堆栈上分配的事实。但是为什么它在Linux中是100 10。
答案 0 :(得分:3)
返回指向超出范围并使用该指针的堆栈分配变量的指针是未定义的行为,纯粹而简单。
但我猜测答案“任何可能发生的事情”都不会为你削减它。
在* nix上会发生什么事情,内存不会被回收,因此它不会被覆盖,而且在胜利时它就是。但这只是猜测,您最好的选择是使用调试器并遍历汇编程序代码。
答案 1 :(得分:0)
你的问题依赖于未定义的行为[1],所以任何事情都可能发生。您甚至不应期望给定操作系统的一致性:诸如编译器选项更改等因素可能会改变行为。
[1] fun1()
返回堆栈中变量的地址,随后将其解除引用。
答案 2 :(得分:0)
Dangling pointer Problem,因此未定义的行为。
答案 3 :(得分:0)
在调用子例程的Linux(或其他操作系统)进程中,局部变量的内存来自进程的堆栈区域。任何动态分配的内存(使用malloc,new等)都来自进程的堆区域。在递归期间,本地存储器在函数调用期间从堆栈区域分配,并在函数执行完成时被清除。
存储器的最低地址位于底部,最高位于顶部。以下是使用快速C代码查找递归中堆栈增长方向的步骤。
#include <stdio.h>
void test_stack_growth_direction(recursion_depth) {
int local_int1;
printf("%p\n", &local_int1);
if (recursion_depth < 10) {
test_stack_growth_direction(recursion_depth + 1);
}
}
main () {
test_stack_growth_direction(0);
}
输出MAC
0x7fff6e9e19ac
0x7fff6f9e89a8
0x7fff6f9e8988
0x7fff6f9e8968
0x7fff6f9e8948
0x7fff6f9e8928
0x7fff6f9e8908
0x7fff6f9e88e8
0x7fff6f9e88c8
0x7fff6f9e88a8
0x7fff6f9e8888
在ubuntu上输出
0x7ffffeec790c
0x7ffffeec78dc
0x7ffffeec78ac
0x7ffffeec787c
0x7ffffeec784c
0x7ffffeec781c
0x7ffffeec77ec
0x7ffffeec77bc
0x7ffffeec778c
0x7ffffeec775c
0x7ffffeec772c
随着内存地址的减少,堆栈在这些特定设置上向下增长。这取决于系统的体系结构,并且可能对其他体系结构具有不同的行为。 0x7fff6f9e8868