2011-11-09 32 views
4

有人可以帮助我理解这些程序的输出。如何为Linux中的进程分配堆栈

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); 
} 

它是100 100在Windows和100 10在Linux上。 Windows输出我可以证明由于局部变量分配在堆栈上的事实。但在Linux中怎么会是100 10呢?

回答

3

将指针返回到超出作用域并使用该指针的堆栈分配变量是未定义的行为,纯粹且简单。

但我猜测答案“任何事情都可能发生”不会为你削减它。

发生什么事是在* nix上内存不回收所以它不会被覆盖,并赢得它。但这只是一个猜测,你最好的选择是使用一个调试器并浏览汇编代码。

0

你的问题依赖于未定义的行为[1],所以任何事情都可能发生。您甚至不应该期望在给定的操作系统上保持一致性:诸如编译器选项更改等因素可能会改变行为。

[1] fun1()返回堆栈中变量的地址,随后取消引用。

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