讲讲堆内存和栈内存

前段时间面试腾讯时候,面试官问了一个很基础的问题:请你说说堆内存和栈内存的区别?

我:基本就是那套模板,例如栈内存是由编译器自动分配和释放,其内存地址在编译期已确定的;主要用来存储局部变量,函数参数以及函数调用的地址等等;对于堆内存来说,其生命周期是由程序员决定的,即程序员手动申请释放,如果没有及时释放,就会造成内存泄漏,当程序结束时,会有操作系统回收未释放的内存。

说完之后,面试官没有立即反应,我以为他不太满意,又接着说了说堆栈的增长方向和内存大小等等…

不知道是我回答的不好还是面试官太高冷,没什么说辞…

本文内容有参考百科,知乎,博客等优秀回答。

1. 从编程语言角度理解不同内存

程序的内存分配:

一个由C/C++编译的程序占用的内存分布:

  • 栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等

  • 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由操作系统回收

  • 全局区(global)/ 静态区(static):

    • data区:已经初始化的全局变量、静态变量和常量
    • bss区:用来存放程序中未初始化的全局变量和静态变量;程序执行前BSS段会自动清0。
    • 常量区:全局区中划分的一个小区域,里面存放的是常量,如const修饰的全局变量、字符串常量
  • 代码区(code):存放函数体的二进制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
@Time : 2020/6/15
@Author : BambooWine
@Mail : 2278816117@qq.com
@Env : win10 + vs2017
*/

#include <cstdio>

int g_a = 10; // 全局变量 data区
int g_b; // 全局变量 bss区
static int s_a = 10; // 静态变量 data区

int main(){
int a = 0; // 栈
char s[] = "abc"; // 栈
char* p1; // 栈
static int s_b = 1; // 静态变量 data区
const char* str = "123"; // "123"在常量区,str在栈区
p1 = (char*)malloc(sizeof(char) * 10); // 申请堆内存
strcpy(p1, "123"); // 123放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方
free(p1);
return 0;
}

2. 从物理层角度理解堆栈内存

不知道大家有没有这样的想法,堆栈不就是内存的不同区,为什么访问速度会有差矣呢?

最近想到了这个问题,但奈何才疏学浅,只能在各种论坛搜索资料。

  • 从硬件上来说,堆和栈最终都是内存条上的若干存储单元,理应并没有什么不同
  • 但是很多CPU对压栈,出栈操作有硬件(指令)上的支持,所以在栈区分配/归还内存速度较快;尤其是函数内部的局部变量,可以轻易与函数调用/返回绑定
  • 由于栈内存分配/回收的特殊机制,使得同一函数内部的”局部变量”总是分配在一段连续的内存空间上

https://blog.csdn.net/yxwb1253587469/article/details/50759604?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-3

https://www.cnblogs.com/jiudianren/p/5671992.html