加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 内存分配堆栈

发布时间:2020-12-16 03:40:40 所属栏目:百科 来源:网络整理
导读:在堆栈中,内存是为main保留的,我们称之为main函数的堆栈帧. 当我们调用Add函数时,内存保留在堆栈顶部.在Add函数堆栈帧中,a和b是局部指针,c是一个计算总和的整数,然后我们返回引用. c是Add函数的局部变量. 现在当Add函数执行完成时,堆栈中的内存空间也被释放,
在堆栈中,内存是为main保留的,我们称之为main函数的堆栈帧.

当我们调用Add函数时,内存保留在堆栈顶部.在Add函数堆栈帧中,a和b是局部指针,c是一个计算总和的整数,然后我们返回引用. c是Add函数的局部变量.

现在当Add函数执行完成时,堆栈中的内存空间也被释放,所以当我们尝试使用指针p访问main中的这个地址时,我们试图访问的内容基本上是一个释放空间.编译器发出警告,但为什么它仍然正确打印值5?

答案可能是机器没有释放内存空间,因为它没有必要,因为没有更多的功能.但是如果我们编写另一个函数Hello,那么它肯定应该在调用堆栈中释放Add函数的空间,但程序仍会打印

Yay     5

是因为在堆中我们需要在释放它之后将指针指向null,否则我们仍然可以访问它?有类似的东西吗?

/* void Hello()
   {
     printf("Yay");
   } */

int* Add(int *a,int *b)
{
  int c=*a+*b;
  return &c;
}

int main()
{
  int a=1,b=4;
  int *p=Add(&a,&b);
  // Hello();
  printf("t%d",*p);
  return 0;
}

解决方法

假设c是局部int变量,在函数调用之后访问c是未定义的行为并且可能打印预期结果,或者可能做一些意外的事情.

虽然C没有强制要求,但通常使用堆栈来实现.出于性能原因,当函数返回时,它会使堆栈区域保持不变.这就是为什么你看到价值5即1 4的原因.但你永远不要指望这一点.

当您使用第二个函数时,行为仍然未定义,因此您可以获得任何输出.实际上,如果在第二个函数中定义另一个变量并使用它,输出可能会改变.

+----------------+
|  c = 42        |
|''''''''''''''''|     +----------------+
|                |     |                |
.  ADD FUNCTION  .     . HELLO FUNCTION .
|                |     |                |
+----------------+     +----------------+
|  b = 4         |     |  b = 4         |
|''''''''''''''''|     |''''''''''''''''|
|  a = 1         |     |  a = 1         |
|''''''''''''''''|     |''''''''''''''''|
|                |     |                |
.  MAIN FUNCTION .     .  MAIN FUNCTION .
|                |     |                |
+----------------+     +----------------+

在上图中,我试图直观地表示当你在Add函数和Hello函数里面时堆栈可能如何堆叠.你可以看到Hello没有搞乱在Add函数中为c保留的堆栈内存.

您可以通过重写Hello函数来验证这一点

void Hello()
{
  int i = 42;
  printf("Yay - %dn",i);
}

可以在主要打印42.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读