Linux 内存分配,malloc(), free(),calloc(),realloc()用法

来源:互联网 发布:淘宝二手车交易 编辑:程序博客网 时间:2024/06/06 00:32

1、内存分类

1、堆栈区(stack):由编译器自动分配与释放,存放函数的参数值,局部变量,临时变量等等,它们获取的方式都是由编译器自动执行的。
2、堆区(heap):一般由程序员分配与释放,基程序员不释放。
3、全局区(静态区)(static):全局变量和静态变量的存储是放在一块儿的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另         一块区域。程序结束后由系统释放。
4、文字常量区:常量字符串是放在这里的,程序结束后由系统释放。
5、程序代码区:存放函数体的二进制代码。

2、在堆上分配内存

1、malloc()函数
malloc()函数可以从堆上获得指定字节的内存空间,其函数声明:void * malloc(size_t n);

形参n为要求 分配的字节数。如果函数执行成功,malloc()返回获得内存空间的首地址;如果函数执行失败,那么返回值为NULL。由于 malloc()函数值的类型为void型指针,因此,可以将其值类型转换后赋给任意类型指针,这样就可以通过操作该类型指针来操作从堆上获得的内存空间。

int *p = NULL;p = (int *)malloc(sizeof(int));if (NULL == p){
printf(“Can’t get memory!\n”);
} memset(p,0,siezeof(int));

注意,
1、malloc()函数分配得到的内存空间是未初始化的。因此,一般在使用该内存空间时,要调用另一个函数memset来将其初始化为全0。memset函数的声明如下:
void * memset (void * p, int c, size_t n);
2、malloc(0)要么返回NULL,要么是一小块可以(并且应该)用free()释放的内存, Linux的malloc(0)行为遵循后者。
3、应该对malloc()的调用应该对返回值进行错误检查,如果返回NULL,设置errno返回错误信息。

2、free()函数

一个程序结束时,必须保证所有从堆上获得的内存空间已被安全释放,否则,会导致内存泄露。
free函数可以实现释放内存的功能。其函数声明为:void free (void * p); 
由于形参为void指针,free函数可以接受任意类型的指针实参。但是,free函数只是释放指针指向的内容,而该指针仍然指向原来指向的地方,此时,指针为野指针,如果此时操作该指针会导致不可预期的错误。

注意:
1、在使用free函数释放指针指向的空间之后,将指针的值置为NULL。
free(p);
p=NULL;
2、如果传给free()的是一个空指针,那么函数什么都不做,也就是说给free()传入一个空指针并不是错误代码。
3、在调用free()后对参数ptr的任何适用,例如再次传递给free()将产生错误,并导致不可预知的结果。
4、使用malloc函数分配的堆空间在程序结束之前必须释放。

调用free()还是不调用free():
在进程终止时,其占用的内存都会被释放返还给操作系统,包括malloc函数申请的内存。因此对于那些分配了内存在进程结束之前持续使用的程序而言,通常会省略对free函数的调用,这在程序中分配了多块内存的情况下可能会特别有用,因为加入多次free的调用不但会消耗大量的CPU时间,还会使代码趋于复杂。

3、calloc函数

calloc函数的功能与malloc函数的功能相似,都是从堆分配内存。其函数声明:void *calloc(int n,int size);
函数返回值为void型指针。如果执行成功,函数从堆上获得size X n的字节空间,并返回该空间的首地址。如果执行失败,函数返回NULL。
注意:该函数与malloc函数的一个显著不同时是,calloc函数得到的内存空间是经过初始化的,其内容全为0。calloc函数适合为数组申请空间,可以将size设置为数组元素的空间长度,将n设置为数组的容量。

4、realloc() 函数

realloc()函数的功能比malloc()函数和calloc()函数的功能更为丰富,可以实现内存分配和内存释放的功能,其原型为:void* realloc (void* ptr, size_t size);
其中ptr必须为需要重新分配的堆内存空间指针,即由malloc函数、calloc函数或realloc函数分配空间的指针;size 为新的内存空间的大小,size 可比原来的大或者小,还可以不变。当 malloc()、calloc() 分配的内存空间不够用时,就可以用 realloc() 来调整已分配的内存。 
注意:
1、如果 ptr 为 NULL,它的效果和 malloc() 相同,即分配 size 字节的内存空间。 
2、如果 size 的值为 0,那么 ptr 指向的内存空间就会被释放,但是由于没有开辟新的内存空间,所以会返回空指针;类似于调用 free()。 
3、realloc()函数可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或是缩小,原有内存的中内容将保持不变。当然,对于缩小,则被缩小的那一部分的内容会丢失。realloc()并不保证调整后的内存空间和原来的内存空间保持同一内存地址。相反,realloc()函数返回的指针很可能指向一个新的内存地址; 
4、我们知道realloc()函数是从堆上分配内存的,当扩大一块内存空间时,realloc()会试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,函数直接返回的指针不变;如果数据后面的字节不够,那么就会使用堆区第一个足够大小的可用内存空间,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上。这句话传递的一个重要的信息就是数据可能被移动。




原创粉丝点击