【问题标题】:How the stack is allocated for the process in linuxlinux中进程的栈是如何分配的
【发布时间】:2011-12-25 05:23:09
【问题描述】:

谁能帮我理解这些程序的输出。

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。

【问题讨论】:

    标签: c stack


    【解决方案1】:

    返回指向超出范围的堆栈分配变量的指针并使用该指针是未定义的行为,纯粹而简单。

    但我猜“任何事情都可能发生”的答案对你来说并不合适。

    发生的情况是,在 *nix 上,内存没有被回收,所以它还没有被覆盖,而在 win 上它是。但这只是一个猜测,您最好的选择是使用调试器并遍历汇编代码。

    【讨论】:

      【解决方案2】:

      您的问题取决于未定义的行为 [1],因此任何事情都可能发生。您甚至不应该期望给定操作系统的一致性:编译器选项的更改等因素可能会改变行为。

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

      【讨论】:

        【解决方案3】:

        Dangling pointer Problem ,因此是未定义的行为。

        【讨论】:

          【解决方案4】:

          在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

          【讨论】:

            猜你喜欢
            • 2015-04-16
            • 1970-01-01
            • 2013-07-14
            • 2016-06-07
            • 2015-04-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-11-23
            相关资源
            最近更新 更多