zoukankan      html  css  js  c++  java
  • C语言内存布局

    典型的C语言的内存分布由以下几块组成:
      • Test segment                               (文本段)
      • Initialzed data segment            (初始化数据段)
      • Uninitialized data segment        (未初始化数据段)
      • Stack                            (栈)
      • Heap                                (堆)

              (图a)
    一:Text segment 文本段
         文本段,通常也被称为是代码段(code segment),简称text,一般包含实际要执行的代码(机器指令)
      作为内存中的一个区域,文本段通常被放置在堆和栈的下面,目的是防止堆或者栈溢出而导致文本段被修改(overwrite),也就是说,文本段是不可修改的。而且,它也是read-only,目的也是防止指令被修改。
      通常情况下,文本段是可以共享的,因此同一时间多个实例之前共享同一份文本段。


    二:Initialized Data Segment 初始化数据段
      也通常被称为数据段,它是一个程序虚拟地址空间的一部分,通常包含了已经初始化好的全局变量和静态变量。
      需要注意的是:数据段并非只读的,很明显,变量的值在程序运行过程中是可以被改变的。
      C语言全局变量  const char* str = "hello";(data segment中)
           静态变量   static int i=10;(data segment中)


    三:Uninitialized data segment        (未初始化数据段)
      通常被称为bss(block started by symbol),在程序执行前这个段中的数据会被内核初始化为0(这似乎是以前的一种做法,不是很明白)
      这个区域主要包含程序未初始化的全局变量,未初始化的静态变量。该段中的变量在执行之前初始化为0或NULL。
      比如:静态声明 static int i; 和 全局变量 int j; 由于没有初始化都将在BBS段

    四:栈
      栈空间通常与堆空间紧邻,并且和堆空间的生长方向相反。如图a所示,stack由高地址区域向低地址区域生长,而heap区则相反,从低地址区域向高地址区域生长。当stack的指针到达了

      heap指针所在的位置时,也就意味这可用内存已经被耗尽了。(当然,随着内存地址增加和虚拟内存技术的发展,它们可以被放置在几乎任何地方,但生长方向仍然相反)
      stack包括了程序栈(LIFO),通常情况下在内存区域的高地址处。在x86的架构下,它向0地址处生长;在其他架构下它可能向其他方向生长。栈指针寄存器(stack pointer)记录栈顶地址,每次有值push进栈就会对栈指针进行修改。一个函数push进栈的一组值被称做堆栈帧(stack frame),堆栈帧保存有返回地址的最小的返回地址。

      栈中存放有自动变量和每次函数调用时的信息。每次函数调用返回地址,一些调用者环境信息(比如寄存器)都被存放在栈中。然后新调用的函数就在栈中为他们的 自动或者临时变量分配内存空间,这就是C中递归函数调用的过程。每次递归函数调用自己,新的堆栈帧就被创建,这样新的变量集合就不会被其他函数实例的变量 集合影响了。
      (可以参考http://blog.csdn.net/yang_yulei/article/details/45795591 ,写的很不错)
    五:堆
      heap是动态内存,由用户管理。通过malloc/alloc/realloc申请空间,通过free释放所申请的空间。


    example:

    #include <stdio.h>
    #include <stdlib.h>
     
    int a;
    static int b;
    void func( void )
    {
        char c;
        static int d;
    }
    int main( void )
    {
        int e;
        int *pi = ( int *) malloc ( sizeof ( int ));
        func ();
        func ();
        free (pi );
        return (0);
    }
    

     
    程序中声明的变量a、b、c、d、e、pi的存储类别和生命期如下所述:
     
      •  a是一个未初始化的全局变量,作用域为整个程序,生命期是整个程序运行期间,在内存的bbs段
      • b是一个未初始化的静态全局变量,作用域为本源文件,生命期是整个程序运行期间,在内存的bbs段
      • c是一个未初始化的局部变量,作用域为函数func体内,即仅在函数体内可见,生命期也是函数体内,在内存的栈中
      • d是一个未初始化的静态局部变量,作用域为函数func体内,即仅在函数体内可见,生命期是整个程序运行期间,在内存的bbs段
      • e是一个未初始化的局部变量,作用域为函数main体内,即仅在函数体内可见,生命期是main函数内,在内存的栈中
      • pi是一个局部指针,指向堆中的一块内存块,该块的大小为sizeof(int),pi本身存储在内存的栈中,生命期是main函数内
      • 新申请的内存块在堆中,生命期是malloc/free之间

    参考:

    • http://www.geeksforgeeks.org/memory-layout-of-c-program/
    • http://www.cnblogs.com/skynet/archive/2011/03/07/1975479.html
  • 相关阅读:
    在QT中应用中文
    DDA画直线
    裁剪算法
    VC6与office2007冲突的解决方法
    肾形图案
    OPENGL函数说明
    基数排序
    Qt信号和槽机制
    分形曼德尔波集合图形
    分形朱利亚集合图形1
  • 原文地址:https://www.cnblogs.com/kakaxisir/p/4915364.html
Copyright © 2011-2022 走看看