概述
一个程序占用的内存通常分为以下几个部分:
代码区、常量区、全局(静态)存储区、堆区、栈区
代码区:
存放程序编译后的二进制代码【代码】
常量区:
存放只读变量和字符串常量,一经初始化,不可修改.【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:请描述一个可执行程序占用的内存分为哪几个区?每个分区各自的作用?所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复