【C/C++教学】关于C/C++中各个区域内存的划分,你知道多少?

2021/6/6 7:21:30

本文主要是介绍【C/C++教学】关于C/C++中各个区域内存的划分,你知道多少?,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

有话先说

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=


我们都知道,

一个程序是由代码和数据构成的。

其中代码是放在代码区,

而数据根据类型和功能  的不同,

又放在不同的区域。

那么关于这些区域是怎么划分的呢?

今天带你一探究竟。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=


01

代码区

顾名思义,

代码区就是存储程序代码的区域。

例如下面的程序:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

像run()函数,

main()函数这些,

以及printf()这些可执行的代码

都是丢到了代码区。

值得注意的是代码区是只读的,

并不可写。


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=



02

栈区

栈区是由编译器在需要的时候分配,

用完会自动清除的一个区域,

通常这个区域存放的是

一些局部变量以及函数的参数等,

栈区的大小一般由编译器决定,

效率比较高,

但空间比较有限。

例如下面的程序:




watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

像其中func函数中的变量a,变量b,

main函数里面的变量val

                            等局部变量

以及调用func函数传入的参数200等,

这些都是存放在栈区的,

存入栈区的变量

会在代码块执行完之后清除。

同学们也可以思考一下:


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=


为什么这里不断循环,

执行int a = 0;

但编译器没有提示重定义的错误。

而这个:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

            编译器会提示变量a重定义了

这里用栈自动清除的特性就很容易解释了,

定义在大括号里面的变量a

是一个局部变量,

for每循环一次,

就执行下面大括号里面的内容一次,

等执行完了整个大括号的内容,

栈自动清除局部变量a,

由于a已经被清除,

下一次循环时再定义a自然不会有问题。

而下面连续在同一代码块

定义多个同名变量,

编译器自然给你一个CE了。


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=



03

堆区


前面说的,

栈区是放局部变量的区域,

大小有限。

那么实际开发中,

要从硬盘中加载一个几GB的大数据文件,

用到更多的内存空间时怎么办?

这时候你就可以用到堆区了!

堆区是由程序员手动申请的,

伴随整个程序运行周期都有效的,

一块内存区域。

堆区的释放编译器可不会管,

需要手动释放的。

如果没有释放掉,

那么只有程序结束时,

操作系统才会自动回收。

C语言中,

可以用malloc函数来申请堆区的内存。

例如下面的程序:



watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

 malo函数结束后,

通过malloc申请的100个字节的内存

并不会被回收,

这一块内存则是从堆区中申请的。

说到这里,

有些邪恶的小伙伴可能已经想到了,

可以来个死循环,

然后不断申请内存,

最终卡死电脑。

 


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=



04

- 全局/静态存储区

这一块区域主要用来,

存储程序的静态变量以及全局变量,

它先于main函数之前分配。

是伴随整个程序的生命周期都存在的。

例如下面的例子:


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

值得一提的是,

字符串常量也是放在静态区的。

从这一点上来说,

我们又可以称字符串常量为无名的静态变量。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=


watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

尾声

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

看了上面的介绍

是不是对内存区域的划分更加清楚了呢

是不是觉得自己的肚子里的墨水又多了呢

小编觉得答案毋庸置疑了>-<

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=





这篇关于【C/C++教学】关于C/C++中各个区域内存的划分,你知道多少?的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程