栈和堆(the stack and the heap)
发布日期:2021-05-08 04:51:27 浏览次数:25 分类:原创文章

本文共 1006 字,大约阅读时间需要 3 分钟。

程序需要用到的内存可以分为四大类:

  • 编译程序的代码区内存
  • 存储全局变量的全局区内存
  • 堆,动态分配的变量所需的内存就是从堆中分配的。
  • 栈,参数和局部变量就是从栈中分配的。
前两个就不多说了,主要说说堆和栈。

堆是一个大的“内存池”,供动态分配内存之用。在C++中,用new 操作符分配的内存就是从堆中分配的。

int *pValue = new int; // pValue is assigned 4 bytes from the heapint *pArray = new int[10]; // pArray is assigned 40 bytes from the heap
我们并不确定将在堆中分配那一块地址,所以new返回的是一个指针。我们连续两次用new分配内存,这两块内存并不一定是连续的。

int *pValue1 = new int;int *pValue2 = new int;// pValue1 and pValue2 may not have sequential addresses

当动态分配的变量删除后,所占用的内存会归还给堆。

堆的利弊:

  1. 内存分配出去后一直被占用,知道归还后才能被其他变量申请。
  2. 动态分配的内存必须用指针才能访问
  3. 以为堆的容量很大,所以大的数组、结构体或者类一般应该分配在堆上。

上面说到,参数和局部变量从栈中分配内存。参数和局部变量属于函数的一部分,所以我们看看函数调用的时候栈上相应的操作。

  1. 将当前函数的指令的地址存储在栈中,当被函数调用结束后cpu根据这个地址返回执行之前的操作。
  2. 在栈中开辟空间,供被调函数返回值所需。
  3. cpu跳到被调用函数中执行
  4. 被调用函数中的局部变量压入栈中。
当被调函数返回时:

  1. 被调用函数返回值的一份拷贝存储在上边2中的空间中。
  2. 栈顶指针回退,栈上的参数和局部变量将销毁
  3. 函数返回值赋值给当前变量
  4. cpu从栈中取出之前存入的指令地址重新执行。
栈溢出

当局部变量分配过大或者函数调用深度过大时就会发生栈溢出,导致程序崩溃。例如:

int main(){    int nStack[100000000];    return 0;}

栈的利弊:

  1. 从栈中分配的变量会随着栈销毁而销毁
  2. 在编译的时候,从栈中分配的内存是连续的,所以可以通过变量名直接访问。
  3. 由于栈空间相对较小,所以大的数组、结构体或者类就不要从栈中分配了。

上一篇:《版本问题!!!!》win10下选择CUDA版本和Cudnn版本,以及匹配tensorflow和Keras。
下一篇:.net core2.2 SignalR多人聊天

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2025年03月29日 07时55分57秒