您的位置:首页 > 运维架构 > Linux

关于Linux C 程序的内存分配

2017-09-02 21:00 363 查看
    根据《unix高级环境编程》书中,一个程序分为如下5段:

代码段(text),data(已初始化)段,bss段(未初始化),栈,堆。

1. 一般情况下,一个可执行的二进制程序拥有3个部分:

可执行的二进制程序 == 代码段 + data 段 + bss 段

2. 程序被加载到内存中,还需要堆区和栈区(栈由系统分配和管理,堆由程序员手动分配和释放)

正在运行的二进制程序 == 代码段 + data段 + bss段 + 堆区 + 栈区
 

3. 动态分配和静态分配,二者最大的区别在于,静态分配是在编译时(complie-time)就已经决定了分配多少内存text+data+bss+stack,而动态分配是直到运行时(Run-time)才分配内存。通过malloc、realloc和calloc分配的内存,必须手动free(). 否则引起内存泄露。

data段和bss段的区别是,bss并不占用可执行文件的大小。

以下具体说明每一段

text段:可执行代码,只读的,字符串常量、const全局;

data段:静态初始化的数据、有初值(不为0)static变量;

bss段:未初始化的全局变量,和全局静态变量;

栈:保存函数的局部变量,函数的参数、返回值或返回的地址;

堆:动态内存分配,程序员手动分配和释放,不释放会引起内存泄露。

附上测试程序:

#include<stdio.h>
#include<malloc.h>
#include<string.h>
const int g_a = 10;//text
int g_b = 20;//data
static int g_c = 30;//data
static int g_d;//bss
int g_e;//bss
char *p1;//bss

int main(void)
{
int l_a ,la; //stack
const int l_b;//stack
static int l_c = 0;//bss
static int l_d;//l_d==0, bss
static int l_e = 5;//data
printf("l_d = %d\n", l_d);
char *p = "123456789"; //p in stack; "123456789" in text
p1 = (char *) malloc(10);//p1 in heap
strcpy(p1, "24680");

printf("high address\n");
printf("------------栈------------\n");
printf("l_a address = %p\n", &l_a);
printf("la address = %p\n", &la);
printf("l_b address = %p\n", &l_b);
printf("------------堆------------\n");
printf("p1 value = %p\n", p1);
printf("------------代码段------------\n");
printf("g_a address = %p\n", &g_a);
printf("------------bss------------\n");
printf("g_d address = %p\n", &g_d);
printf("g_e address = %p\n", &g_e);
printf("p1 address = %p\n", &p1);
printf("l_c address = %p\n", &l_c);
printf("l_d address = %p\n", &l_d);
printf("------------data------------\n");
printf("g_b address = %p\n", &g_b);
printf("g_c address = %p\n", &g_c);
printf("l_e address = %p\n", &l_e);
printf("low address\n");

return 0;
}
执行结果:
root@liujie-desktop:/soft# ./t
l_d = 0
high address
------------栈------------
l_a address = 0xbfe5db8c
la address = 0xbfe5db88
l_b address = 0xbfe5db84
------------堆------------
p1 value = 0x9295008
------------代码段------------
g_a address = 0x8048710
------------bss------------
g_d address = 0x804a034
g_e address = 0x804a044
p1 address = 0x804a040
l_c address = 0x804a03c
l_d address = 0x804a038
------------data------------
g_b address = 0x804a020
g_c address = 0x804a024
l_e address = 0x804a028
low address从结果来分析,
1. const 全局 g_a 存放在text;

2. const 局部 l_b 存放在栈中;

3. l_c 初始化为0 其实和l_d是一样的,l_d也为0,存放在bss,&p1也在bss;

备注:编译时需要加 -g 选项,这样才可以看elf信息;

readelf  -a  t  可以看到其中的.data .text. .bss。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: