天气越来越冷啦,大家一定要注意防寒保暖哦~
那么回到正题,虽然天气建议我们待在被窝,但是我们可是要成为(程序员)的男人!怎么能在这关键的阶段不学习呢?所以今天,我们还是继续来分享我们的C语言知识——内存布局。
C程序的典型内存表示包括以下部分。
1.文本段
2.初始化数据段
3.未初始化数据段
4.堆栈
5.堆
正在运行的进程的典型内存布局
1.文本段:
文本段,也称为代码段或简称为文本,是目标文件或内存中程序的一部分,其中包含可执行指令。
作为内存区域,可以在堆或堆栈下方放置一个文本段,以防止堆和堆栈溢出覆盖它。
通常,文本段是可共享的,因此对于频繁执行的程序(例如文本编辑器,C编译器,shell等),仅一个副本需要存储在内存中。另外,文本段通常是只读的,以防止程序意外修改其指令。
2.初始化数据段:
初始化数据段,通常简称为数据段。数据段是程序的虚拟地址空间的一部分,其中包含由程序员初始化的全局变量和静态变量。
请注意,数据段不是只读的,因为可以在运行时更改变量的值。
该段可以进一步分为初始化的只读区域和初始化的读写区域。
例如,在C中由char s [] =“ hello world”定义的全局字符串以及在主(即全局)外部的int debug = 1之类的C语句将存储在初始化的读写区域中。像const char * string =“ hello world”这样的全局C语句使字符串文字“ hello world”存储在初始化的只读区域中,而字符指针变量字符串存储在初始化的读写区域中。
例如:静态int i = 10将存储在数据段中,而全局int i = 10也将存储在数据段中
3.未初始化的数据段:
未初始化的数据段,通常称为“ bss”段,以古老的汇编运算符命名,其代表“以符号开头的块”。在程序开始执行之前,内核将该段中的数据初始化为算术0。
未初始化的数据从数据段的末尾开始,包含所有初始化为零或在源代码中没有显式初始化的全局变量和静态变量。
例如,一个声明为static int i的变量;将包含在BSS段中。
例如,一个声明为int j的全局变量;将包含在BSS细分中。
4.堆栈:
堆栈区域传统上与堆区域相邻,并且朝相反的方向生长。当堆栈指针遇到堆指针时,可用内存就用完了。(借助现代的大型地址空间和虚拟内存技术,它们几乎可以放置在任何地方,但它们通常仍会朝相反的方向生长。)
堆栈区域包含程序堆栈(一种LIFO结构),通常位于内存的较高部分。在标准PC x86计算机体系结构上,它向地址零增长;在其他一些架构上,它的发展方向相反。“堆栈指针”寄存器跟踪堆栈的顶部。每次将值“推入”堆栈时都会对其进行调整。为一个函数调用推入的一组值称为“堆栈帧”;堆栈帧至少包含一个返回地址。
堆栈,用于存储自动变量,以及每次调用函数时保存的信息。每次调用一个函数时,将返回的地址和有关调用者环境的某些信息(例如某些机器寄存器)都保存在堆栈中。然后,新调用的函数在堆栈上为其自动和临时变量分配空间。这就是C中的递归函数如何工作的方式。每次递归函数调用自身时,都会使用一个新的堆栈框架,因此一组变量不会干扰该函数另一个实例的变量。
5.堆:
堆是通常进行动态内存分配的段。
堆区域从BSS段的末尾开始,并从那里扩展到更大的地址。堆区域由malloc,realloc和free管理,它们可以使用brk和sbrk系统调用来调整其大小(请注意使用不需要brk / sbrk和单个“堆区”来满足malloc / realloc / free的约定;它们也可以使用mmap来实现,以将虚拟内存的潜在不连续区域保留到进程的虚拟地址空间中) 。堆区域由进程中的所有共享库和动态加载的模块共享。
以上就是今天学习的内容,希望对大家有帮助哦~