我是靠谱客的博主 清新钢笔,最近开发中收集的这篇文章主要介绍C:请描述一个可执行程序占用的内存分为哪几个区?每个分区各自的作用?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一个程序占用的内存通常分为以下几个部分:

代码区、常量区、全局(静态)存储区、堆区、栈区

代码区:
存放程序编译后的二进制代码【代码】

常量区:
存放只读变量和字符串常量,一经初始化,不可修改.【const变量、字符串】

全局(静态)存储区:
全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,
未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。因此,又可以分为.data段和.bss段。

.data段:
存放已初始化的全局和静态变量。在编译器编译的时候,会给已初始化的数据分配内存空间,数据保存在目标文件中。
.bss段:
(bss是英文Block Started by Symbol的简称。)存放未初始化或初始化为0的全局和静态变量。在编译器编译的时候,不会给该段的数据分配空间,只是记录数据所需的空间大小。

堆区:
由程序员手动申请/释放,若不手动释放,程序结束后由系统回收.【malloc申请的内存】

栈区:
由系统自动分配/释放,存放函数参数,局部变量等.【局部变量、函数参数】


从编译和执行的角度,描述如下:

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

★★可执行二进制程序 = 代码段(.text)+初始化数据段(.data)+未初始化数据段(.bss)★★

2.而当程序被加载到内存单元时,则需要另外两个域:堆域和栈域。图1-1所示为可执行代码存储态和运行态的结构对照图。一个正在运行的C程序占用的内存区域分为代码段(有些书中将常量包含在代码段)、初始化数据段、未初始化数据段(BSS)、堆、栈5个部分。
★★正在运行的C程序 = 代码段(.text)+初始化数据段(.data)+未初始化数据段(.bss)+堆(.heap)+栈(.stack)★★

3.在将应用程序加载到内存空间执行时,操作系统负责代码段、数据段和BSS段的加载,并将在内存中为这些段分配空间。栈亦由操作系统分配和管理,而不需要程序员显示地管理;堆段由程序员自己管理,即显示地申请和释放空间。

4.动态分配与静态分配,二者最大的区别在于:1. 直到Run-Time的时候,执行动态分配,而在compile-time的时候,就已经决定好了分配多少Text+Data+BSS+Stack。2.通过malloc()动态分配的内存,需要程序员手工调用free()释放内存,否则容易导致内存泄露,而静态分配的内存则在进程执行结束后系统释放(Text,
Data), 但Stack段中的数据很短暂,函数退出立即被销毁。


思考:
C:请描述一个可执行程序占用的内存分为哪几个区?每个分区各自的作用?
C:谈谈内存分配中的(.data)段和(.bss)段的区别?为什么要分.data段和.bss段?
C:谈谈内存分配中的堆和栈的区别?为什么要有堆区和栈区呢?


不同类型的变量,编译执行的时候,在内存中的位置也不一样。
#include <stdio.h>
#include <stdlib.h>
#include <string.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;            //栈  
    int           local_B;            //栈  
    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("hight addressn");  
    printf("-------------栈--------------n");  
    printf( "栈,    局部变量,                           local_A, addr:0x%08xn", &local_A );  
    printf( "栈,    局部变量,(后进栈地址相对local_A低)  local_B, addr:0x%08xn", &local_B );  
    printf("-------------堆--------------n");  
    printf( "堆,    malloc分配内存,             p1,      addr:0x%08xn", p1 );  
    printf("------------BSS段------------n");  
    printf( "BSS段, 全局变量,       未初始化    g_E,     addr:0x%08xn", &g_E, g_E );      
    printf( "BSS段, 静态全局变量,   未初始化,   g_D,     addr:0x%08xn", &g_D );  
    printf( "BSS段, 静态局部变量,   初始化,     local_C, addr:0x%08xn", &local_C);  
    printf( "BSS段, 静态局部变量,   未初始化,   local_D, addr:0x%08xn", &local_D);  
    printf("-----------数据段------------n");  
    printf( "数据段,全局变量,       初始化      g_B,     addr:0x%08xn", &g_B);  
    printf( "数据段,静态全局变量,   初始化,     g_C,     addr:0x%08xn", &g_C);  
    printf("-----------代码段------------n");  
    printf( "代码段,全局初始化变量, 只读const,  g_A,     addr:0x%08xnn", &g_A);  
    printf("low addressn");  
    return;  
}  
执行结果:
hight address
---------------------------,    局部变量,                           local_A, addr:0x1408b158,    局部变量,(后进栈地址相对local_A低)  local_B, addr:0x1408b15c
---------------------------,    malloc分配内存,             p1,      addr:0x121a010
------------BSS段------------
BSS段, 全局变量,       未初始化    g_E,     addr:0x601070
BSS段, 静态全局变量,    未初始化,   g_D,     addr:0x60105c
BSS段, 静态局部变量,    初始化,     local_C, addr:0x601060
BSS段, 静态局部变量,    未初始化,   local_D, addr:0x601064
-----------数据段------------
数据段,全局变量,        初始化      g_B,     addr:0x601050
数据段,静态全局变量,     初始化,     g_C,     addr:0x601054
-----------代码段------------
代码段,全局初始化变量,   只读const,  g_A,     addr:0x400838

low address

参考:
     https://blog.csdn.net/yyc1023/article/details/52749226


收录于:
嵌入式软件/BSP开发工程师/Linux驱动工程师/C语言经典笔试面试题大全

最后

以上就是清新钢笔为你收集整理的C:请描述一个可执行程序占用的内存分为哪几个区?每个分区各自的作用?的全部内容,希望文章能够帮你解决C:请描述一个可执行程序占用的内存分为哪几个区?每个分区各自的作用?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部