1、 栈区:由编译器自动分配和释放,只要存放函数的参数值,局部变量值等等
2、 堆区:由程序员分配和释放。malloc() realloc() calloc()的区别
3、 全局区或静态区:存放全局变量和静态变量,程序结束时由系统进行释放。这个区又分为两部分 –全局初始化区,和全局未初始化区。
4、 字符常量区:常量字符串存放于此,程序结束时由系统释放。
5、 程序代码区:存放函数体的二进制代码。
下面用一段代码来说明他们的存放位置:
//main.c
Int a = 0 ; // 全局初始化区
Char *p1 ;// 全局未初始化区
Void main(){
Int b ; // 栈
Char s[] = “dxd” ; //栈
Char *p2 ; //栈
Char *p3 = “123” ; // p3在栈 “123”在常量字符区
Static int c = 0 ; //全局区
P1 = malloc(10) ; //在堆上
Strcpy(p1,”123”) ;//这条语句编译器可能会优化,p1去指向那个字符串。
}
介绍常用的几个分配控件的函数:
malloc() memory allocation动态内存分配。
函数原型 extern void *malloc(unsigned int num_bytes)
《功能》
分配一个大小为num_bytes的空间。
《返回值》
是void*类型,意思就是未确定类型的指针。如果分配成功则返回分配好的空间的首地址,如果不成功则返回NULL。
calloc()
函数原型 void *calloc(unsigned n, unsigned size)
《功能》
在内存的动态存储区分配n个长度为size的连续控件,返回一个指针指向分配好的空间,如果分配不成功则返回NULL
《跟malloc的区别》
Calloc在动态分配完空间之后,会自动初始化该内存空间为0,而malloc则不会初始化,里面的数据是随机的!
realloc()
函数原型 extern void *realloc(void *mem_address, unsigned_int newsize)
《功能》:
重新为某个指针所指的空间分配大小,这里要注意的是,newsize一定要大于之前空间的大小。如果小于原来的大小的话,就会造成数据丢失!
《返回值》:
如果重新分配空间成功的话,就返回新的地址,否则返回NULL
《这个函数的执行步骤》:
第一种情况:原来内存后面有足够的控件,够newsize的大小
第一步:在原来的内存的后面开辟一段内存,使它等于newsize的大小。
第二步:返回原来的地址。
第二种情况:
第一步:在堆上分配一个newsize大小的控件。
第二步:将*mum_address中所指的内容复制到新开辟的内存空间中。
第三步:释放*mum_address返回新的地址.
《特殊情况》:
如果newsize的大小是0的话,那么释放mum_address并返回null
《使用realloc()的总结》
1. realloc失败的时候,返回NULL
2. realloc失败的时候,原先的内存不会释放,移动和改变
3. 假如原来的内存后面有足够去newsize占据的空间,那么realloc返回的地址不会变,就是原来的地址,只不过他的控件变大了。假如原来的内存后面没有足够的空间让newsize占据,那么realloc就会重新开辟一段空间,然后把原来控件里的数据复制过来,并且free掉以前的空间,返回新的地址。
free()
函数原型:void free(void *ptr)
功能:释放ptr所指的内心空间。
这里需要注意的是,释放完ptr所指的空间后,ptr通常会被放入可用存储池,以后可以接受内存开辟函数的返回值。 但是,但是!如果我们free这个指针后,并且打算以后都不用这个指针了,我们通常会在free后面把这个指针置空!