程序员的自我修养——链接,装载与库(七)内存
-
内存是承载程序的运行介质,也是程序进行各种运算和表达的场所。 应用程序的内存布局为:栈,堆,可执行文件的映像和保留区。 栈(高地址->低地址)用于维护函数调用的上下文,离开了栈,函数调用无法实现。 堆(低地址->高地址)用于储存应用程序动态分配内存的内存区域。 可执行文件映像用于存储可执行文件在内存中的映像。 保留区存储内存中收到保护而非禁止访问的对象。 动态链接库映射区用于存储装载的动态链接库。 程序中出现的段错误或非法访问有两种原有:第一:初始化为nullptr的指针的使用。第二:没有对栈上的对象进行初始化。 栈存储了函数调用所需要的维护信息,常常被称为栈帧。栈帧一般包括:函数的返回地址和参数,临时变量,保存的上下文。 调用惯例是函数的调用方和函数的被调用方对于函数如何调用所遵守的规则。 函数的调用惯例会规定一些规定:函数参数的传递顺序和方式,栈的维护方式,名字修饰的策略。 如果函数的返回值类型的尺寸太大,C语言在函数返回时会使用一个临时的栈上内存区域作为中转,结果返回值对象会被拷贝两次。 栈上的数据在函数返回的时候会被释放掉。因此栈中的数据无法传递到函数外部(栈中的数据自动释放),而全局变量和静态变量不能动态的产生,在编译时期就已经定义了,因此堆(堆中的数据手动释放)是唯一的选择。 malloc()的实现是程序向操作系统申请一块适当大小的堆空间,然后由程序自己管理堆内存(因为系统调用的开销很大),具体而要管理着堆空间的往往是程序的运行库。 堆分配算法:空闲链表,位图和对象池。
