栈、堆、全局区/静态存储区、常量区、代码段、到底是什么?

一、程序运行内存分布图

我们知道一个由我们编写好的程序,运行时,我们的程序中写的代码,定义的变量,写的函数、for 循环等等,这些运行时都分布在内存中的哪里吗?
一下是一个程序运行时 内存的各个区域的分布
在这里插入图片描述
详细的每个区域存放的内容如下

二、栈

没错,是不是想到了 数据结构的栈:
在这里插入图片描述
栈 遵循后进先出先进后出的 存储顺序,那么这个栈和我们的程序运行又有什么大的联系呢?
看一段代码示例:

#include <stdio.h>
void Fun4()
{
	printf("4\n");
}
void Fun3()
{
	printf("3\n");
	Fun4();
}
void Fun2()
{
	printf("2\n");
	Fun3();
}
void Fun1()
{
	printf("1\n");
	Fun2();
}
int main()
{
	Fun1();
	return 0;
}

是的 是一段非常无聊且易懂的代码,函数调用关系图为:
在这里插入图片描述
调试代码并 打开VS2017 的堆栈窗口
在这里插入图片描述
该图表示函数的调用过程 自底向上调用,函数执行完之后,该函数生命周期结束,函数退出,就像栈的 pop 操作,直到所有的函数调用完之后,栈底只有一个 main 函数 , main 函数执行完之后 最终整个程序也结束掉。
在这里插入图片描述
栈的空间一般是由系统分配的,一般存储着局部变量、函数参数、函数返回值等,一般大小为 1M 、2M 等 ;
在内存中的位置为:
且是向下分配空间
在这里插入图片描述
示例局部变量定义:

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	int c = 0;
	printf("%p\n", &a);
	printf("%p\n", &b);
	printf("%p\n", &c);
	return 0;
}

在这里插入图片描述
可以看到 局部变量 a b c 的地址依次变低,也证实了栈的空间地址分配时 从高到低

三、堆

注意 这个堆 可不是 数据结构里面的堆, 这里的堆 是专门开辟出来 给我们程序员 动态申请内存使用的,例如 我们 malloc 、new 出来的空间 这部分都在堆上
与栈相反的是,我们动态申请的空间是 由低地址到高地址的
在这里插入图片描述
代码示例:

#include <stdio.h>
int main()
{
	int *p = (int*)malloc(8);
	int *p1 = (int*)malloc(8);
	printf("%p\n", p);
	printf("%p\n", p1);
	//同时 使用完申请的空间之后要记得释放,否则会造成内存泄漏,
	//且释放之后,不能再次释放 否则会造成非法操作、越界访问,导致程序崩溃
	free(p);
	p = NULL;
	free(p1);
	p1 = NULL;
	return 0;
}

打印结果:
在这里插入图片描述

3.2 堆与栈的区别

空间管理方式不同:

1.栈上的空间由系统分配并管理、不需要我们关心申请与释放
2.堆上的空间是我们自己申请并负责释放、如果忘记释放会造成内存泄漏、多次释放也会导致越界访问、非法操作、甚至导致程序崩溃问题等,这是需要我们程序员自己注意的地方

内存分配方向不同

1.栈上的空间是从高地址向低地址分配
2.堆上的空间是从低地址向高地址分配

分配效率不同

1.栈是由系统分配管理,更加贴合系统底层、效率更高
2.堆的申请和释放是由库函数支持,由我们自己手动调用库函数进行申请内存和释放内存,且容易产生内存碎片的问题,效率低于栈

存放内容不同

1.栈主要存放局部变量、函数返回值、函数参数、函数地址等、程序运行过程中的函数调用就是栈来完成的、函数调用逐个入栈、调用完成之后逐个弹出
2.堆主要为我们动态申请空间服务,为我们开辟空间

四、全局区/静态存储区

这里主要存放 全局变量和 静态变量、生命周期覆盖整个程序、直到程序结束,生命周期结束、不过这里还细分了是否初始化的全局变量和静态变量,但是大体是在一个区域内存放
例如:

#include <stdio.h>
int n = 0;//全局区
int arry[10];//全局区
int main()
{
	static int i = 0;//静态存储区
	return 0;
}

五、常量区

例如如下:

string str1 = "helloworld";
int n = 6;
"helloworld 和 6 都属于常量、不允许被修改

六、代码区

存放代码、不允许被修改,也就是我们所写的函数,是存放在这里的
代码区中的东西是随整个程序一起的,启动时 生、结束时 亡
有时候放在代码段的不只是代码,还有const类型的常量,还有字符串常量。(const类型的常量、字符串常量有时候放在常量区有时候放在代码段,取决于平台)

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值