关于Linux C 程序的内存分配

    根据《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。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值