1.可执行文件结构:
1)代码区:包含操作码和操作对象、常量数据(const声明)、立即数,代码区是共享的, 只提供只读。
2)全局/静态数据区:包含被初始化的全局数据和初始化静态数据。
3)未初始化数据区(BBS):包含未初始化的全局数据和未初始化静态数据。
2.进程结构:
1)代码区:加载可执行程序代码段,由加载器完成。
2)全局数据区:加载可执行文件数据段,数据生存周期为整个程序运行过程。
3)未初始化数据区:加载未初始化数据,数据生存周期为整个程序运行过程。
4)栈区:由编译器自动分配,存放函数的参数值,返回值,局部变量,函数完成调用则释放。
5)堆区:动态分配内存,由程序员自己分配与释放,若程序员没释放,则最后由os释放。
3.堆和栈的区别:
栈由系统自动管理由allocal()函数完成申请,自动完成释放,是一片连续的区域向下扩展,空间有限制,超过会溢出;
堆是向高地址扩展的不连续区域,由malloc/free(new/delete)申请/释放,效率低,而且会产生较多的碎片。
4.内存管理常用函数:
1)malloc()/free()(c++中:new/delete):动态分配/释放内存
2)realloc():用来更改堆中已经配置的内存空间
3)calloc():把分配的内存初始化为0,用法与malloc()相似
4)allocal():为栈分配内存,自动释放
5)memcopy():从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
6)memmove():用于从src拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中
7)memset():一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
8)memcmp() :比较内存区域buf1和buf2的前count个字节
9)memchr():从buf所指内存区域的前count个字节查找字符ch
5.memcopy()的实现:
1 void * memcopy ( void * dest, const void * src, size_t num ) 2 { 3 char* pdes = (char*)dest; 4 char* psrc = (char*)src; 5 assert(dest !=NULL && src !=NULL && num>0); 6 while(num--) 7 *pdes++ = *psrc++; 8 return dest; 9 }
6.memmove()的实现:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<assert.h> 5 void * memmove ( void * dest, const void * src, size_t num ) 6 { 7 char* pdes = (char*)dest; 8 char* psrc = (char*)src; 9 assert(dest !=NULL && src !=NULL && num>0); 10 //判断dest和src是否存在重叠 11 if(pdes+num <psrc || psrc+num < pdes) //不存在重叠,正常从前向后复制 12 while(num--) 13 *pdes++ = *psrc++; 14 else //存在重叠,从后向前复制 15 { 16 pdes = pdes+num-1; 17 psrc = psrc+num-1; 18 while(num--) 19 *pdes-- = *psrc--; 20 } 21 return dest; 22 } 23 int main() 24 { 25 int const N=30; 26 char dest[N]; 27 char* src="hello world."; 28 printf("%s\n",src); 29 memset(dest,0,N*sizeof(char)); 30 char *result=(char*)memmove(dest,src,strlen(src)); 31 printf("%s\n",result); 32 return 0; 33 }
7.memmove()与memcopy()区别:
在内存没有发生折叠时,两者的作用相同,当内存发生折叠时,memmove()可以保证输出结果正确,memcopy()不能保证,memcopy()是memmove()的一个子集。