C程序的内存布局

原创 2017年06月06日 10:28:34

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。

CSDN视频网址:http://edu.csdn.net/lecturer/144

C程序的典型内存表示由以下部分组成

1、文本片段

2、初始化数据片段

3、未初始化数据片段

        4、栈

        5、堆

运行过程的典型内存布局

文本片段

文本段(也称为代码段或简称为文本)是目标文件或内存中程序的一个部分,其中包含可执行指令。
作为存储器区域,文本段可以放置在堆或堆栈下方,以防止堆和堆栈溢出覆盖它。
通常,文本段是可共享的,因此只有一个副本需要在经常执行的程序的内存中,例如文本编辑器,C编译器,shell等等。 此外,文本段通常是只读的,以防止程序意外修改其指令。

初始化数据片段

初始化的数据段,通常简称Data Segment。 数据段是程序的虚拟地址空间的一部分,其中包含由程序员初始化的全局变量和静态变量。
请注意,数据段不是只读的,因为变量的值可以在运行时更改。
该段可以进一步分为初始化只读区和初始化读写区。
例如,C中的char [] =“hello world”定义的全局字符串和主要(即全局)之外的int debug = 1等C语句将被存储在初始化的读写区域中。 而一个全局C语句,如const char * string =“hello world”使得字符串文字“hello world”存储在初始化的只读区域中,并且字符指针变量字符串在初始化的读写区域中。
再举一例子:static int i = 10将被存储在数据段中,并且全局int i = 10也将存储在数据段中。

未初始化数据片段

未初始化的数据段,通常称为“bss”段,以古代汇编器运算符命名,代表“块由符号启动”。该段中的数据在程序开始执行之前由内核初始化为0

未初始化的数据从数据段的末尾开始,并包含初始化为零或在源代码中没有显式初始化的所有全局变量和静态变量。
例如,一个变量声明为静态int i; 将包含在BSS部分。
例如,一个全局变量声明为int j; 将包含在BSS部分。

区域传统上与堆区域相邻并且生长相反的方向;当栈指针遇到堆指针时,可用内存耗尽。 (使用现代大型地址空间和虚拟内存技术,它们几乎可以放置在任何地方,但它们通常也会呈现相反的方向)

栈区域包含程序
栈,LIFO结构,通常位于内存的较高部分。在标准的PC x86计算机体系结构上,它向地址零增长;在其他一些系统上,它的方向也相反。 “堆栈指针”寄存器跟踪堆栈的顶部;每次将值“推”到堆栈时都会进行调整。用于一个函数调用的一组值被称为“堆栈帧”;堆栈帧至少包含返回地址。

堆栈,其中存储自动变量,以及每次调用函数时保存的信息。每次调用一个函数时,将返回的地址和一些关于
调用者的信息(如某些机器寄存器)保存在堆栈中。新调用的函数然后在堆栈中为其自动和临时变量分配空间。这是C中的递归函数如何工作。每次递归函数调用自身时,都会使用一个新的堆栈帧,所以一组变量不会干扰另一个函数实例的变量。

堆是动态内存分配通常发生的部分。

堆区域开始于BSS段的末尾,并从那里增长到较大的地址。堆区域由malloc,realloc和free管理,可以使用brk和sbrk系统调用来调整其大小(请注意,使用 brk / sbrk和单个“堆区”不需要满足malloc / realloc / free;也可以使用mmap实现,以将虚拟内存的潜在非连续区域保留到进程的虚拟地址空间中。 堆区域由一个进程中的所有共享库和动态加载的模块共享。

举例说明:

 1、看下面简单的程序片段:
#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

以上就是关于C语言中的内存布局。。。。。。。



版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

c程序内存布局

当一个程序被编译连接为可执行程序时,对于c/c++语言的程序,其内存布局主要是代码段和数据段。代码段text 存放可以执行的代码,拥有可执行权限,一般是只读的。代码段在执行时一般都需要访问内存数据,即...

C++程序内存布局

下面 解释图片映射的信息 从低地址到高地址 代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存种的镜像。 数据段:数据段用来存放可执行文件中已初始化全局变量 BSS段:...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

C程序内存布局

C程序编译的完整过程:C源代码---->预编译处理(.c)---->编译、优化程序(.s、.asm)---->汇编代码(.obj、.o、.a、.ko)---->链接程序(.exe、.elf、.axf ...

c程序内存布局

c程序内存布局 我在我之前的博客中曾经写过关于c程序数据内存分配的问题,那时候我们只是简单的描述了一下代码区,静态存储区,常量区,堆区,栈区,你可以查看一下之前的文章,景天我们来说一点c程序内存布局...

C程序内存布局

一个程序本质上都是由 BSS 段、data段、text段三个组成的。这样的概念在当前的计算机程序设计中是很重要的一个基本概念,而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配...

C++程序内存布局

C++程序内存布局探讨(一) 刘昕 重庆大学软件学院 摘要: 本文探讨了C++程序内存布局的基础知识,对堆、栈、全局数据区和代码区的概念进行了简单介绍,并介绍了内存对齐和进程地址空间(虚拟内存)方面的...

c/c++程序的内存布局

程序代码段: 代码段是用来存放可执行文件的操作指令,它是可执行程序在内存中的映像。代码段需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作——它是不可写的。程序数据段: 存放...

C程序(进程)的内存布局

C程序(进程)的内存布局 #include const int a = 10; //全局常量a int main(void) {   const int b = 20; //局部常量b...

C程序(进程)的内存布局

这篇文章是转载博友的,链接如下 http://www.cnblogs.com/dejavu/archive/2012/08/13/2627498.html 在编写程序的过程中,内存是一个非常重...

程序的 内存布局

内存布局
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)