【问题标题】:Variables in Stack & Heap堆栈和堆中的变量
【发布时间】:2014-12-09 17:35:48
【问题描述】:

根据本文所写的内容

http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html#sec-6

理解堆栈的一个关键是,当一个函数 退出,它的所有变量都从堆栈中弹出(因此 永远失去)。因此堆栈变量本质上是局部的。

因此,堆栈中属于该函数的所有变量都被弹出,除了返回给函数的值(或者可能为父函数重新分配?),或者它不是静态的。

但是这个特殊的程序完全可以正常工作。

#include<stdio.h>

int* func()
{
int a=6;
int *b;
b=&a;
printf("in func - %d \n",*b);

return b;
}

void func2()
{
    int a,c;
    a=99;
    c=2*a;
    printf("in func 2 - %d \n",c);
}

void main()
{
int *b;
b=func();
func2();
printf("in main - %d",*b);
}

输出:

C:\Users\Shaurya\Desktop>gcc asw.c

C:\Users\Shaurya\Desktop>a
in func - 6
in func 2 - 198
in main - 6
C:\Users\Shaurya\Desktop>

我认为用户分配的变量(使用 calloc、malloc、realloc)可以被其他函数访问,因为它们在堆中,正如文章所说。 但是,如果我们创建一个指向堆栈中的局部变量的指针,并返回该指针,那么该变量也可以在其他函数中访问。

【问题讨论】:

  • 从不。曾经。说。 “完全没问题”。
  • 尝试在调用funcprintf之间调用另一个函数。
  • 当某些东西从堆栈中弹出时,它不会被删除!但是堆栈已被释放,因此可以(并且将)在那些局部变量的位置写入其他内容。因此,您的示例有效,因为您在调用 func 后没有调用任何其他函数,但这并不意味着可以保证
  • 似乎不起作用。我应该尝试更大的功能吗?结果已作为编辑发布。

标签: c stack heap-memory


【解决方案1】:

您正在返回地址,它看起来是正确的,因为没有任何东西可以替换该位置的内存内容。不保证会出现这种情况。如果你在 func 和 printf 之间调用一个函数,那么你可能会得到不同的结果

【讨论】:

  • 似乎不起作用。我应该尝试更大的功能吗?结果已作为编辑发布。
  • @ShauryaChaudhuri 抱歉,我这么晚才回来,但所有重要的 cmets 都已在其他答案中提出:)
【解决方案2】:

通过返回局部变量的地址(并尝试在调用者中取消引用它),您的程序会调用未定义的行为。未定义行为的一种可能结果是您的程序似乎可以正常工作。但是,如果您更改代码以在调用 funcprintf 之间调用另一个函数(尤其是创建和设置局部变量的函数),您可能会得到不同的结果。

a 曾经占用的内存单元1 显然仍然存在,并且将包含a 的最后一个值,直到有其他东西覆盖它。你只是碰巧在其他任何东西到达之前访问了那个记忆单元。


1。我们在这里讨论的是虚拟内存,而不是物理内存。

【讨论】:

  • 似乎不起作用。我应该尝试更大的功能吗?结果已作为编辑发布。
  • @John Bode 不清楚为什么“记忆”脚注。 a 使用的内存单元即使在物理内存中仍然存在,并且将包含 a 的最后一个值,直到其他东西覆盖它(或重新启动)。
  • @ShauryaChaudhuri:可能有多种原因;再次强调,func 的行为是undefined,几乎任何结果(包括看起来正常工作)都是可能的。您不应依赖此行为是可重复或可预测的。返回 auto 变量的地址并试图在变量的生命周期之外取消引用它是一个编码错误,句号。
  • @chux:只是想强调一个独立于任何物理架构的抽象内存模型。显然,在没有虚拟内存的系统上,我们谈论的是物理内存单元。
  • 似乎足够有效。因此,在函数调用权之后,内存可能会被编辑,也可能不会被编辑。这是完全不可预测的。也许有一次它按预期给出了 o/p,有时它可能会覆盖以前的堆栈内存空间并给出一个完全不同的 o/p。我的理解正确吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
  • 2013-06-27
  • 2019-06-15
  • 1970-01-01
  • 2014-06-23
  • 1970-01-01
相关资源
最近更新 更多