zoukankan      html  css  js  c++  java
  • 深入C语言内存区域分配(进程的各个段)详解(转)

    原文地址:http://www.jb51.net/article/39696.htm

    一般情况下,一个可执行二进制程序(更确切的说,在Linux操作系统下为一个进程单元,在UC/OSII中被称为任务)在存储(没有调入到内存运行)时拥有3个部分,分别是代码段(text)、数据段(data)和BSS段。这3个部分一起组成了该可执行程序的文件

    (1)代码段(text segment):存放CPU执行的机器指令。通常代码段是可共享的,这使得需要频繁被执行的程序只需要在内存中拥有一份拷贝即可。代码段也通常是只读的,这样可以防止其他程序意外地修改其指令。另外,代码段还规划了局部数据所申请的内存空间信息。

    代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

    (2)数据段(data segment):或称全局初始化数据段/静态数据段(initialized data segment/data segment)。该段包含了在程序中明确被初始化的全局变量、静态变量(包括全局静态变量和局部静态变量)和常量数据。

    (3)未初始化数据段:亦称BSS(Block Started by Symbol)。该段存入的是全局未初始化变量、静态未初始化变量。
    而当程序被加载到内存单元时,则需要另外两个域:堆域和栈域。

    (4)栈段(stack):存放函数的参数值、局部变量的值,以及在进行任务切换时存放当前任务的上下文内容。

    (5)堆段(heap):用于动态内存分配,即使用malloc/free系列函数来管理的内存空间。
    在将应用程序加载到内存空间执行时,操作系统负责代码段、数据段和BSS段的加载,并将在内存中为这些段分配空间。栈段亦由操作系统分配和管理,而不需要程序员显示地管理;堆段由程序员自己管理,即显示地申请和释放空间。

    另外,可执行程序在运行时具有相应的程序属性。在有操作系统支持时,这些属性页由操作系统管理和维护。

    下面给出示例程序代码,注释已经在代码中写明:

    /*代码段、数据段和BSS段存储变量类型*/
    #include <stdio.h>
    const int    g_A       = 10;            //代码段
    int            g_B       = 20;            //数据段
    static int    g_C       = 30;            //数据段
    static int    g_D;                    //BSS段
    int            g_E;                    //BSS段
    char        *p1;                    //BSS段
    void main( )
    {
        int           local_A;            //栈
        static int    local_C = 0;        //数据段
        static int    local_D;            //数据段

        char        *p3 = "123456";     //123456在代码段,p3在栈上
        p1 = (char *)malloc( 10 );      //堆,分配得来得10字节的区域在堆区
        strcpy( p1, "123456" );         //123456{post.content}放在常量区,编译器可能会将它与p3所指向 的"123456"优化成一块
        printf(" ");
        printf( "代码段,全局初始化变量, 只读const,  g_A,     addr:0x%08x ", &g_A);
        printf(" ");
        printf( "数据段,全局变量,       初始化      g_B,     addr:0x%08x ", &g_B);
        printf( "数据段,静态全局变量,   初始化,     g_C,     addr:0x%08x ", &g_C);
        printf(" ");
        printf( "BSS段, 全局变量,       未初始化    g_E,     addr:0x%08x ", &g_E, g_E );    
        printf( "BSS段, 静态全局变量,   未初始化,   g_D,     addr:0x%08x ", &g_D );
        printf( "BSS段, 静态局部变量,   初始化,     local_C, addr:0x%08x ", &local_C);
        printf( "BSS段, 静态局部变量,   未初始化,   local_D, addr:0x%08x ", &local_D);
        printf(" ");
        printf( "栈,    局部变量,                   local_A, addr:0x%08x ", &local_A );
        printf(" ");
        printf( "堆,    malloc分配内存,             p1,      addr:0x%08x ", p1 );
    }

  • 相关阅读:
    网曝!互联网公司那些老司机才懂的秘密~~
    中国IT行业薪资:与销售相比,程序员真得很“穷”
    太简单了,教你去掉Java代码中烦人的“!=null”
    怎么判断自己在不在一家好公司?
    内部泄露版!互联网大厂的薪资和职级一览
    重磅!GitHub突然宣布,对全球人免费开放全部核心功能
    痛心!Pandownload开发者被抓!我终于决定使用Docker搭建一个多端同步网盘!
    退税:我承认我有赌的成分
    golang实现的简单优先队列
    ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (13)解答
  • 原文地址:https://www.cnblogs.com/windfall/p/5100484.html
Copyright © 2011-2022 走看看