栈和堆(the stack and the heap)

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

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

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

int *pValue = new int; // pValue is assigned 4 bytes from the heap
int *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. 由于栈空间相对较小,所以大的数组、结构体或者类就不要从栈中分配了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值