malloc的全称是memory allocation,中文叫动态内存分派,用于要求一块一连的指定大小的内存块地区以void*范例返回分派的内存地区地点,当没法晓得内存细致位置的时刻,想要绑定真正的内存空间,就须要用到动态的分派内存。
void* 范例示意未确定范例的指针。C,C++划定,void* 范例能够经由过程范例转换强迫转换为任何别的范例的指针。
平常需和free函数配对运用。
函数定义
原型
extern void *malloc(unsigned int num_bytes);
头文件
#include <stdlib.h>
函数声明
void *malloc(size_t size);
备注:void* 示意未确定范例的指针,void *能够指向任何范例的数据,更明白的说是指要求内存空间时还不晓得用户是用这段空间来存储什么范例的数据(比方是char照样int或许其他数据范例)。
返回值
假如分派胜利则返回指向被分派内存的指针(此存储区中的初始值不确定),不然返回空指针NULL。当内存不再运用时,应运用free()函数将内存块开释。函数返回的指针一定要恰当对齐,使其能够用于任何数据对象。
申明
关于该函数的原型,在之前malloc返回的是char型指针,新的ANSIC范例划定,该函数返回为void型指针,因而必要时要举行范例转换。它能向体系要求分派一个长度为num_bytes(或size)个字节的内存块。
平常它需和free函数配对运用。free函数能开释某个动态分派的地点,表明不再运用这块动态分派的内存了,完成把之前动态要求的内存返还给体系。
相干函数
calloc、realloc、free、_alloca。
与new的区分
从本质上来讲,malloc(Linux上细致完成能够参考man malloc,glibc经由过程brk()&mmap()完成)是libc内里完成的一个函数,假如在source code中没有直接或许间接include过stdlib.h,那末gcc就会报出error:‘malloc’ was not declared in this scope。假如生成了目的文件(假定动态链接malloc),假如运转平台上没有libc(Linux平台,手动指定LD_LIBRARY_PATH到一个空目录即可),或许libc中没有malloc函数,那末会在运转时(Run-time)失足。new则不然,是c++的关键字,它本身不是函数。new不依赖于头文件,c++编译器就能够把new编译成目的代码(g++4.6.3会向目的中插进去_Znwm这个函数,别的,编译器还会依据参数的范例,插进去响应的组织函数)。
在运用上,malloc 和 new 至少有两个差别: new 返回指定范例的指针,而且能够自动盘算所须要大小。比方:
int *p; p = new int; //返回范例为int *范例(整数型指针),分派大小为sizeof(int);
或:
int *parr; parr = new int[100]; //返回范例为int *范例(整数型指针),分派大小为sizeof(int) * 100;
而 malloc 则必需要由我们盘算字节数,而且在返回后强行转换为现实范例的指针。
int *p; p = (int*)malloc(sizeof(int) * 128); //分派128个(可依据现实须要替代该数值)整型存储单元, //并将这128个一连的整型存储单元的首地点存储到指针变量p中 double *pd = (double*)malloc(sizeof(double) * 12); //分派12个double型存储单元, //并将首地点存储到指针变量pd中
第一、malloc 函数返回的是 void * 范例。
关于C++,假如你写成:p = malloc (sizeof(int)); 则顺序没法经由过程编译,报错:“不能将 void* 赋值给 int * 范例变量”。
所以必需经由过程 (int *) 来将强迫转换。而关于C,没有这个要求,但为了使C顺序更轻易的移植到C++中来,发起养成强迫转换的习气。
第二、函数的实参为 sizeof(int) ,用于指明一个整型数据须要的大小。
须要注重一个特殊情况malloc(0),返回值多是一个NULL或许一个有用的地点(能够平安的free,然则不能解援用)。注重malloc(-1)不是制止的,参数为无标记范例,假如是负数能够会转换成极大的正数,末了平常会由于没有足够大的内存块而返回NULL。
在范例的顺序中我们有必要根据如许的花样去运用malloc及free:
type *p; if(NULL == (p = (type*)malloc(sizeof(type)))) /*请运用if来推断,这是有必要的*/ { perror("error..."); exit(1); } .../*别的代码*/ free(p); p = NULL;/*请加上这句*/
malloc 也能够到达 new [] 的效果,要求出一段一连的内存,要领无非是指定你所须要内存大小。
比方想分派100个int范例的空间:
int *p = (int*)malloc(sizeof(int) * 100); //分派能够放得下100个整数的内存空间。
别的有一点不能直接看出的区分是,malloc 尽管分派内存,并不能对所得的内存举行初始化,所以取得的一片新内存中,其值将是随机的。
除了分派及末了开释的要领不一样之外,经由过程malloc或new取得指针,在别的操纵上保持一致。
对其做一个惯例补充
char *ptr; if((ptr = (char*)malloc(0)) == NULL) puts("Gotanullpointer"); else puts("Gotavalidpointer");
此时能够会取得的是Got a valid pointer,也能够会取得Got a null pointer。
事情机制
malloc函数的本质体现在,它有一个将可用的内存块衔接为一个长长的列表的所谓余暇链表。挪用malloc函数时,它沿衔接表寻觅一个大到足以满足用户要求所须要的内存块。然后,将该内存块一分为二(一块的大小与用户要求的大小相称,另一块的大小就是剩下的字节)。接下来,将分派给用户的那块内存传给用户,并将剩下的那块(假如有的话)返回到衔接表上。挪用free函数时,它将用户开释的内存块衔接到余暇链上。到末了,余暇链会被切成许多的小内存片断,假如这时候用户要求一个大的内存片断,那末余暇链上能够没有能够满足用户要求的片断了。因而,malloc函数要求延时,并最先在余暇链上翻箱倒柜地搜检各内存片断,对它们举行整顿,将相邻的小余暇块兼并成较大的内存块。假如没法取得符合要求的内存块,malloc函数会返回NULL指针,因而在挪用malloc动态要求内存块时,一定要举行返回值的推断。
Linux Libc6采纳的机制是在free的时刻试图整合相邻的碎片,使其兼并成为一个较大的free空间。
顺序示例
一般顺序
typedef struct data_type{ int age; char name[20]; }data; data*bob=NULL; bob=(data*)malloc(sizeof(data)); if(bob!=NULL) { bob->age=22; strcpy(bob->name,"Robert"); printf("%s is %d years old.\n",bob->name,bob->age); } else { printf("mallocerror!\n"); exit(-1); } free(bob); bob=NULL;
输出效果:Robert is 22 years old.
内存走漏实例
#include <stdio.h> #include <malloc.h> #define MAX 100000000int main(void)
{ int *a[MAX] = {NULL}; int i; for(i=0;i<MAX;i++) { a[i]=(int*)malloc(MAX); } return 0; }
注:malloc要求以后没有检测返回值。
引荐教程:C#视频教程
以上就是malloc函数的用法的细致内容,更多请关注ki4网别的相干文章!