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程序的内存布局(Memory Layout)

C语言程序的内存布局 C语言程序的内存布局结构,包括连接过程中目标程序各个段的组成和运行过程中各个段加载的情况。 C语言程序在内存中各个段的组成 C语言程序连接过程中的特性和常见错误 C语言程序的运行...
  • gatieme
  • gatieme
  • 2015年02月06日 20:26
  • 17132

C语言内存模型及运行时内存布局

BSS段(bss segment) 通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。 ...
  • u013033371
  • u013033371
  • 2013年12月03日 18:04
  • 3789

C 程序的内存空间布局

C 程序的内存空间布局表格中, 从上到下为高地址到低地址方向 segment 含义 argument and environment 命令行参数和环境变量(环境表和环境字符串) st...
  • why19911024
  • why19911024
  • 2016年11月04日 11:54
  • 651

C++ 内存布局:深入理解C++内存布局

1、虚函数简介       虚函数的实现要求对象携带额外的信息,这些信息用于在运行时确定该对象应该调用哪一个虚函数。典型情况下,这一信息具有一种被称为vptr(virtual table point...
  • QQrenzai
  • QQrenzai
  • 2016年06月24日 10:36
  • 1715

使用汇编分析c代码的内存分布

深入了解c内存分析.
  • shaohuazuo
  • shaohuazuo
  • 2014年12月14日 23:38
  • 1300

c++内存布局最完整

大家都应该知道C++的精髓是虚函数吧? 虚函数带来的好处就是: 可以定义一个基类的指针, 其指向一个继承类, 当通过基类的指针去调用函数时, 可以在运行时决定该调用基类的函数还是继承类的函数. 虚函数...
  • Watson2016
  • Watson2016
  • 2017年03月31日 22:29
  • 240

c程序内存布局

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

C程序内存布局

C程序编译的完整过程:C源代码---->预编译处理(.c)---->编译、优化程序(.s、.asm)---->汇编代码(.obj、.o、.a、.ko)---->链接程序(.exe、.elf、.axf ...
  • qq_21111579
  • qq_21111579
  • 2015年10月24日 11:57
  • 365

程序的内存布局——函数调用栈的那点事

[注]此文是《程序员的自我修养》的读书总结,其中掺杂着一些个人的理解,若有不对,欢迎拍砖。 程序的内存布局 现代的应用程序都运行在一个虚拟内存空间里,在32位的系统里,这个内存空间拥有4G...
  • yang_yulei
  • yang_yulei
  • 2015年05月22日 00:14
  • 9824

字节序,C程序内存布局

 【技术】【转】字节序问题--大端法小端法 一、字节序定义字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数据当然就无需谈顺序的问题了)。其实大部分人在...
  • sking2008
  • sking2008
  • 2011年05月06日 14:38
  • 166
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C程序的内存布局
举报原因:
原因补充:

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