|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
安装和登录命令:login、shutdown、halt、reboot、mount、umount、chsh
orisun@orisun-desktop:~/Program$sizememory2
textdatabssdechexfilename
2074284162374946memory2
能够看到一个可实行程序在存储(没有调进内存)时分为代码区,数据区,未初始化数据区三部分。
(1)代码区寄存CPU实行的呆板指令。一般代码区是共享的,即别的实行程序可挪用它。
(2)数据区寄存已初始化的全局变量,静态变量(包含全局和部分的),常量。static全局变量和static函数只能在以后文件中被挪用。
(3)未初始化数据区(uninitializeddatasegment,BSS)寄存全局未初始化的变量。BSS的数据在程序入手下手实行之前被初始化为0或NULL。
代码区地点的地点空间最低,往上顺次是数据区和BSS区,而且数据区和BSS区在内存中是紧挨着的。
可实行程序在运转时又多出了两个地区:栈区和堆区。
(4)栈区。由编译器主动开释,寄存函数的参数值,部分变量等。每当一个函数被挪用时,该函数的前往范例和一些挪用的信息被存储到栈中。然后这个被挪用的函数再为它的主动变量和一时变量在栈上分派空间。每挪用一个函数一个新的栈就会被利用。栈区是从洼地址位向低地点位增加的,是一块一连的内涵地区,最年夜容量是由体系事后界说好的,请求的栈空间凌驾这个界线时会提醒溢出,用户能从栈中猎取的空间较小。
(5)堆区。用于静态内存分派,位于BSS和栈两头的地点位。由程序员请求分派(malloc)和开释(free)。堆是从低地点位向洼地址位增加,接纳链式存储布局。频仍地malloc/free形成内存空间的不一连,发生碎片。当请求堆空间时库函数依照必定的算法搜刮可用的充足年夜的空间。因而堆的效力比栈要低的多。
举个例子申明各类变量寄存在甚么区:
inta=0;//a在全局已初始化数据区
char*p1;//p1在BSS区(未初始化全局变量)
main()
{
intb;//b为部分变量,在栈区
chars[]="abd";//s为部分数组变量,在栈区
//"abc"为字符串常量,存储在已初始化数据区
char*p1,*p2;//p1,p2为部分变量,在栈区
char*p3="123456";//p3在栈区,1234560在已初始化数据区
staticintc=0;//c为部分(静态)数据,在已初始化数据区
//静态部分变量会主动初始化(由于BSS区主动用0或NULL初始化)
p1=(char*)malloc(10);//分派得来的10个字节的地区在堆区
p2=(char*)malloc(20);//分派得来的20个字节的地区在堆区
free(p1);
free(p2);
p1=NULL;//显现地将p1置为NULL,制止今后毛病地利用p1
p2=NULL;
}
我们再写一个程序,输入各变量的内存空间:
#include<stdio.h>
#include<malloc.h>
#include<unistd.h>
#include<alloca.h>
externvoidafunc(void);
externetext,edata,end;
intbss_var;//未初始化全局变量存储在BSS区
intdata_var=42;//初始化全局就是存储在数据区
#defineSHW_ADR(ID,I)printf("the%8stisataddress:%8xn",ID,&I);//打印地点宏
intmain(intargc,char*argv[])
{
char*p,*b,*nb;
printf("Addressetext:%8xtAddressedata%8xtAddessend%8xtn",&etext,&edata,&end);
SHW_ADR("main",main);//检察代码段main函数地位
SHW_ADR("afunc",afunc);//检察代码段afunc函数地位
printf("nbssLocatoin:n");
SHW_ADR("bss_var",bss_var);//检察BSS段变量地点
printf("ndataLocation:n");
SHW_ADR("data_var",data_var);//检察数据段变量
printf("nStackLoation:n");
afunc();
p=(char*)alloca(32);//从栈平分配空间
if(p!=NULL)
{
printf("nthecharpinstackstartfrom:t",p);
printf("nthecharpinstackendin:t",(p+32*sizeof(char)));
}
b=(char*)malloc(32*sizeof(char));//从堆平分配空间
nb=(char*)malloc(16*sizeof(char));//从堆平分配空间
printf("nHeapLocations:n");
printf("theHeapstart:%pn",b);//堆肇端地点
printf("theHeapEnd:%pn",(nb+16*sizeof(char)));//堆停止地位
printf("np,bandnbinStackn");
SHW_ADR("p",p);//显现栈中数据p的地位
SHW_ADR("b",b);//显现栈中数据b的地位
SHW_ADR("nb",nb);//显现栈中数据nb的地位
free(b);//开释请求的空间,以免内存保守
free(nb);
}
voidafunc(void)
{
staticintlonglevel=0;//静态数据存储在数据段中
intstack_var;//部分变量,存储在栈区
if(++level==5)
return;
printf("stack_varisat:%pn",&stack_var);
SHW_ADR("stack_varinstacksection",stack_var);
SHW_ADR("Levalindatasection",level);
afunc();
}
运转了局显现:
Addressetext:8048818Addressedata804a028Addessend804a038
themainisataddress:80484d4
theafuncisataddress:80486e3
bssLocatoin:
thebss_varisataddress:804a034
dataLocation:
thedata_varisataddress:804a024
StackLoation:
stack_varisat:0xbff4a87c
thestack_varinstacksectionisataddress:bff4a87c
theLevalindatasectionisataddress:804a030
stack_varisat:0xbff4a84c
thestack_varinstacksectionisataddress:bff4a84c
theLevalindatasectionisataddress:804a030
stack_varisat:0xbff4a81c
thestack_varinstacksectionisataddress:bff4a81c
theLevalindatasectionisataddress:804a030
stack_varisat:0xbff4a7ec
thestack_varinstacksectionisataddress:bff4a7ec
theLevalindatasectionisataddress:804a030
thecharpinstackstartfrom:
thecharpinstackendin:
HeapLocations:
theHeapstart:0x9b24008
theHeapEnd:0x9b24040
p,bandnbinStack
thepisataddress:bff4a8b8
thebisataddress:bff4a8b4
thenbisataddress:bff4a8b0
剖析:
因为afunc函数嵌套挪用本人,以是很快就把栈空间用完了(sfunc只被挪用了四次)。如许一来p=(char*)alloca(32)想再从栈中请求空间就失利了。
内存办理函数:
void*malloc(size_tsize)
voidfree(void*ptr)
(typedefunsignedintsize_t;
这里拔出一段对void*的注释:
void*这不叫空指针,这叫无切实范例指针.这个指针指向一块内存,却没有告知程序该用何种体例来注释这片内存.以是这类范例的指针不克不及间接举行取内容的操纵.必需先转成其余范例的指针才能够把内容注释出来.
另有0,这也不是空指针所指的内容.0是暗示一个字符串的开头罢了,并非NULL的意义.
真实的空指针是说,这个指针没有指向一块成心义的内存,好比说:
char*k;
这里这个k就叫空指针.我们并未让它指向恣意地址.
又大概
char*k=NULL;
这里这个k也叫空指针,由于它指向NULL也就是0,注重是整数0,不是0
一个空指针我们也没法对它举行取内容操纵.
空指针只要在真正指向了一块成心义的内存后,我们才干对它取内容.也就是说要如许
k="helloworld!";
这时候k就不是空指针了.)
malloc在内存的静态存储区平分配一个长度为size字节的一连空间,其参数是无称呼整型,前往一个指向所分派的一连空间的肇端地点的指针。分派空间不乐成(如内存不敷)时前往一个NULL指针。
free开释失落内存空间。
这两个函数的库头文件为stdlib.h.
void*realloc(void*ptr,size_tsize)
当必要扩展一块内存空间时realloc试图间接从堆确当前内存段前面取得更多的内涵空间,并前往原指针;假如空间不敷就利用第一个可以满意这个请求的内存块,并将以后数据复制到新地位,开释本来的数据块;假如请求空间失利,前往NULL。
calloc是malloc的复杂包装,它把静态分派的内存空间举行初始化,全体清0。此函数的完成形貌:
void*calloc(size_tnmemb,size_tsize)
{
void*p;
size_ttotal;
total=nmemb*size;
p=malloc(total);
if(p!=NULL)//请求空间
memset(p,0,total);//初始化0
returnp;
}
alloca()函数在栈平分配size个内存空间(函数前往时主动开释失落空间,无需程序员手动开释),并将空间初始化为0。
在这里你会学到更多的知识,学习linux,更要学习一种geek的精神,python之禅中也说过:以总结分享为荣,以跪求其解为耻; |
|