内存、栈、堆

网友投稿 734 2022-05-30

内存、栈、堆

一般应用程序内存空间有如下区域:

栈:由操作系统自动分配释放,存放函数的参数值、局部变量等的值,用于维护函数调用的上下文

堆:一般由程序员分配释放,若程序员不释放,程序结束时可能由操作系统回收,用来容纳应用程序动态分配的内存区域

可执行文件映像:存储着可执行文件在内存中的映像,由装载器装载是将可执行文件的内存读取或映射到这里

保留区:保留区并不是一个单一的内存区域,而是对内存中受到保护而禁止访问的内存区域的总称,如通常 C 语言讲无效指针赋值为 0(NULL),因此 0 地址正常情况下不可能有效的访问数据

栈保存了一个函数调用所需要的维护信息,常被称为堆栈帧(Stack Frame)或活动记录(Activate Record),一般包含以下几方面:

函数的返回地址和参数

临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量

保存上下文:包括函数调用前后需要保持不变的寄存器

堆分配算法:

空闲链表(Free List)

位图(Bitmap)

对象池

典型的非法指针解引用造成的错误。当指针指向一个不允许读写的内存地址,而程序却试图利用指针来读或写该地址时,会出现这个错误。

普遍原因:

将指针初始化为 NULL,之后没有给它一个合理的值就开始使用指针

没用初始化栈中的指针,指针的值一般会是随机数,之后就直接开始使用指针

内存、栈、堆

编译链接

预编译(预编译器处理如 #include、#define 等预编译指令,生成 .i 或 .ii 文件)

编译(编译器进行词法分析、语法分析、语义分析、中间代码生成、目标代码生成、优化,生成 .s 文件)

汇编(汇编器把汇编码翻译成机器码,生成 .o 文件)

链接(连接器进行地址和空间分配、符号决议、重定位,生成 .out 文件)

现在版本 GCC 把预编译和编译合成一步,预编译编译程序 cc1、汇编器 as、连接器 ld

MSVC 编译环境,编译器 cl、连接器 link、可执行文件查看器 dumpbin

编译器编译源代码后生成的文件叫做目标文件。目标文件从结构上讲,它是已经编译后的可执行文件格式,只是还没有经过链接的过程,其中可能有些符号或有些地址还没有被调整。

可执行文件(Windows 的 .exe 和 Linux 的 ELF)、动态链接库(Windows 的 .dll 和 Linux 的 .so)、静态链接库(Windows 的 .lib 和 Linux 的 .a)都是按照可执行文件格式存储(Windows 按照 PE-COFF,Linux 按照 ELF)

Windows 的 PE(Portable Executable),或称为 PE-COFF,.obj 格式

Linux 的 ELF(Executable Linkable Format),.o 格式

Intel/Microsoft 的 OMF(Object Module Format)

Unix 的 a.out 格式

MS-DOS 的 .COM 格式

PE 和 ELF 都是 COFF(Common File Format)的变种

Linux Windows 汇编语言

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:泛微数字化办公助力东方雨虹实现企业门户升级、落地统一办公平台
下一篇:再探 智能指针
相关文章