这一篇笔记是由一个突然的认识触发的:在开发软件的很多地方,很多概念都是有生命周期的,比如宏观的软件工程生命周期,微观的android的activity 界面的生命周期,服务器客户端通信的生命周期,还有我最近才想到的,写代码过程中内存的生命周期。从这个角度切入,能够全局系统的了解某个概念,无记忆负担。理解代码也有一条很清晰的主线。想到之前对内存管理的理解都是零散的知识点,今天记住了明天可能忘,各种混乱不踏实,各种累啊。
目前层次上c语言的编程就是对系统api和内存的操作,下面以一个经典的笔试题来说明内存的生命周期:
实现字符串逆序
1 char* src="abcd"; //申请内存,指明内存的数据类型 src指向的是静态存储区上常量字符串"abcd"的首地址;
2 char* des=NULL; //声明数据类型,指向null
3 int length=strlen(src);//
4 des=(char*)malloc(length+1);//申请内存 des指向的是堆上连续空间为10个字节的内存的首地址
5 char* d=des;//用d标示符来指向刚申请的内存,以待操作。
6 char* s=&src[length-1];//用s标示符来指向字符串的尾部,以待操作。
7 while(length--!=0)//
{
8 *d++=*s--;//操作内存,给内存赋值,并移动内存
9 }
10 *d=0;//添加字符串结束符
11 printf("%s",des);//
12 free(des);//释放内存
13 des=NULL;//
我在代码的右边给了比较详尽的注释,从内存生命周期的角度,可以分为下面3步
第一步:申请内存,程序内存的产生,可以使用常量(静态存储区),malloc(堆),new(堆)。如第1,4行
第二步:操作内存,通过各种赋值,移动,来达到想要的业务效果。如第5, 6,8行。
第三步:释放内存。如第12行。
补充说明,对内存的引用,如src,d,s等,都分配在栈上,是由编译器自动管理,无需我们手工控制。哪些地方需要手工控制内存释放呢,一般来说用了malloc,new申请的内存,我们需要用free,delete去释放掉。