C程序的内存布局

    C程序的典型内存表示包括以下部分。

  1. 文本段(Text segment)
  2. 初始化的数据段(Initialized data segment)
  3. 未初始化的数据段(Uninitialized data segment)
  4. 栈(Stack)
  5. 堆(Heap)
    在这里插入图片描述
        运行过程的典型内存布局
        1.文本段:
        文本段,也称为代码段或简单地称为文本,是目标文件或内存中程序的一部分,其中包含可执行指令。
        作为内存区域,文本段可以放在堆或栈的下面,以防止堆和栈溢出覆盖它。
        通常,文本段是可共享的,因此对于频繁执行的程序(例如文本编辑器,C编译器,shell等),只需要在内存中保存一个副本即可。此外,文本段通常是只读的,以防止程序意外修改其指令。
        2.初始化的数据段:
        初始化的数据段,通常简称为数据段。数据段是程序的虚拟地址空间的一部分,其中包含由程序员初始化的全局变量和静态变量。
        注意,数据段不是只读的,因为变量的值可以在运行时更改。
        该段可以进一步分为初始化的只读区域和初始化的读写区域。
        例如,C中char s[]=“hello world”定义的全局字符串和main(例如global)之外的int debug=1等C语句将存储在初始化的读写区域中。像const char*string=“hello world”这样的全局C语句使字符串文字“hello world”存储在初始化的只读区域中,而字符指针变量string存储在初始化的读写区域中。
        例如:static int i = 10将存储在数据段中,而global int i = 10也将存储在数据段中。
        3.未初始化的数据段:
        未初始化的数据段通常称为“bss”段,以古老的汇编运算符命名,其代表“block started by symbol”。在程序开始执行之前,内核将该段中的数据初始化为算术0。
        例如,声明为static int i;的变量将包含在BSS段中。
        例如,声明为 int j;的全局变量将包含在BSS段中。
        4.栈:
        栈区域传统上与堆区域相邻,并以相反的方向增长。当栈指针遇到堆指针时,可用内存耗尽。(利用现代的大地址空间和虚拟内存技术,它们几乎可以放在任何地方,但它们通常还是朝相反的方向生长。)
        栈区域包含程序栈,一种后进先出结构,通常位于内存的较高部分。在标准的PC x86计算机体系结构上,它向地址零增长;在其他一些体系结构上,它向相反的方向增长。“栈指针”寄存器跟踪栈的顶部,每次将值“推”到栈上时都会对其进行调整。为一个函数调用推送的一组值称为“栈帧”,栈帧至少由一个返回地址组成。
        栈,用于存储自动变量,以及每次调用函数时保存的信息。每次调用一个函数时,返回的地址和有关调用者环境的某些信息(如一些机器寄存器)都保存在栈上。然后,新调用的函数在栈上为其自动变量和临时变量分配空间。这就是C中递归函数的工作方式。每次递归函数调用自身时,都会使用一个新的栈帧,因此一组变量不会干扰该函数另一个实例的变量。
        5.堆:
        堆是通常进行动态内存分配的部分。
        堆区域从BSS段的末尾开始,并从那里扩展到更大的地址。堆区域由malloc,realloc和free管理,它们可以使用brk和sbrk系统调用来调整其大小(请注意,不需要使用brk/sbrk和单个“堆区域”来履行malloc/realloc/free,也可以使用mmap来实现它们,以将虚拟内存的潜在不连续区域保留到进程的虚拟地址空间中)。堆区域由进程中的所有共享库和动态加载的模块共享。

    示例:
    size(1)命令报告文本、数据和bss段的大小(以字节为单位)。
    1.检查以下简单的C程序

#include <stdio.h>

int main(void)
{
	return 0;
}
[narendra@CentOS]$ gcc memory-layout.c -o memory-layout
[narendra@CentOS]$ size memory-layout
text       data        bss        dec        hex    filename
960        248          8       1216        4c0    memory-layout

    2.让我们在程序中添加一个全局变量,现在检查bss的大小。

#include <stdio.h>

int global; /* Uninitialized variable stored in bss*/

int main(void)
{
	return 0;
}
[narendra@CentOS]$ gcc memory-layout.c -o memory-layout
[narendra@CentOS]$ size memory-layout
text       data        bss        dec        hex    filename
 960        248         12       1220        4c4    memory-layout

    3.让我们添加一个静态变量,该变量也存储在bss中。

#include <stdio.h>

int global; /* Uninitialized variable stored in bss*/

int main(void)
{
	static int i; /* Uninitialized static variable stored in bss */
	return 0;
}
[narendra@CentOS]$ gcc memory-layout.c -o memory-layout
[narendra@CentOS]$ size memory-layout
text       data        bss        dec        hex    filename
 960        248         16       1224        4c8    memory-layout

    4.让我们初始化静态变量,然后将其存储在数据段(DS)中。

#include <stdio.h>

int global; /* Uninitialized variable stored in bss*/

int main(void)
{
	static int i = 100; /* Initialized static variable stored in DS*/
	return 0;
}
[narendra@CentOS]$ gcc memory-layout.c -o memory-layout
[narendra@CentOS]$ size memory-layout
text       data        bss        dec        hex    filename
960         252         12       1224        4c8    memory-layout

    5.让我们初始化全局变量,然后将其存储在数据段(DS)中。

#include <stdio.h>

int global = 10; /* initialized global variable stored in DS*/

int main(void)
{
	static int i = 100; /* Initialized static variable stored in DS*/
	return 0;
}
[narendra@CentOS]$ gcc memory-layout.c -o memory-layout
[narendra@CentOS]$ size memory-layout
text       data        bss        dec        hex    filename
960         256          8       1224        4c8    memory-layout
参考文档

[1]Narendra Kangralkar.Memory Layout of C Programs[EB/OL].https://www.geeksforgeeks.org/memory-layout-of-c-program/,2021-02-03.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值