C语言程序编译时的内存分配

 

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后面把这个指针置空!

你可能感兴趣的:(c,null,语言,编译器,Allocation)