您的位置:首页 > 编程语言 > C语言/C++

【c基础知识】内存分区

2017-10-12 19:42 162 查看
首先我们来了解一下什么是数据类型?为什么需要数据类型?

数据类型是为了更好进行内存的管理,让编译器能确定分配多少内存。

数据类型基本概念:

Ø 类型是对数据的抽象;

Ø 类型相同的数据具有相同的表示形式、存储格式以及相关操作;

Ø 程序中所有的数据都必定属于某种数据类型;

Ø 数据类型可以理解为创建变量的模具:
固定大小内存的别名;



这里特别要提一下void类型

void字面意思是”无类型”,void* 无类型指针,无类型指针可以指向任何类型的数据。

void定义变量是没有任何意义的,当你定义void a,编译器会报错。

void真正用在以下两个方面:

Ø 对函数返回的限定;

Ø 对函数参数的限定;

我们要想执行我们编写的c程序,那么第一步需要对这个程序进行编译。

1)预处理:宏定义展开、头文件展开、条件编译,这里并不会检查语法
2)编译:检查语法,将预处理后文件编译生成汇编文件
3)汇编:将汇编文件生成目标文件(二进制文件)
4)链接:将目标文件链接为可执行程序
当我们编译完成生成可执行文件之后,我们通过在linux下size命令可以查看一个可执行二进制文件基本情况:



在没有运行程序前,也就是说程序没有加载到内存前,可执行程序内部已经分好3段信息,分别为代码区(text)、数据区(data)和未初始化数据区(bss)3
个部分(有些人直接把data和bss合起来叫做静态区或全局区)。


l 代码区

存放 CPU 执行的机器指令。通常代码区是可共享的(即另外的执行程序可以调用它),使其可共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。代码区通常是只读的,使其只读的原因是防止程序意外地修改了它的指令。另外,代码区还规划了局部变量的相关信息。

 

l 全局初始化数据区/静态数据区(data段)

该区包含了在程序中明确被初始化的全局变量、已经初始化的静态变量(包括全局静态变量和局部静态变量)和常量数据(如字符串常量)。

 

l 未初始化数据区(又叫 bss 区)

存入的是全局未初始化变量和未初始化静态变量。未初始化数据区的数据在程序开始执行之前被内核初始化为 0 或者空(NULL)。

总体来讲说,程序源代码被编译之后主要分成两种段:程序指令和程序数据。代码段属于程序指令,而数据域段和.bss段属于程序数据。
程序在加载到内存前,代码区和全局区(data和bss)的大小就是固定的,程序运行期间不能改变。然后,运行可执行程序,操作系统把物理硬盘程序load(加载)到内存,除了根据可执行程序的信息分出代码区(text)、数据区(data)和未初始化数据区(bss)之外,还额外增加了栈区、堆区

栈区

由系统进行内存的管理。主要存放函数的参数以及局部变量。在函数完成执行,系统自行释放栈区内存,不需要用户管理。

堆区

由编程人员手动申请,手动释放,若不手动释放,程序结束后由系统回收,生命周期是整个程序运行期间。使用malloc或者new进行堆的申请。

全局/静态区

全局静态区内的变量在编译阶段已经分配好内存空间并初始化。这块内存在程序运行期间一直存在,它主要存储全局变量静态变量常量



总结:

在理解C/C++内存分区时,常会碰到如下术语:数据区,堆,栈,静态区,常量区,全局区,字符串常量区,文字常量区,代码区等等,初学者被搞得云里雾里。在这里,尝试捋清楚以上分区的关系。
数据区:堆,栈,全局/静态存储区。
全局/静态存储区:常量区,全局区、静态区。
常量区:字符串常量区、常变量区。
代码区:存放程序编译后的二进制代码,不可寻址区。

可以说,C/C++内存分区其实只有两个,即代码区和数据区。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 标准 内存 分区