C语言中的malloc使用详解
一、原型:externvoid*malloc(unsignedintnum_bytes);
头文件:#include<malloc.h>或#include<alloc.h>(注意:alloc.h与malloc.h的内容是完全一致的。)
功能:分配长度为num_bytes字节的内存块
说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
当内存不再使用时,应使用free()函数将内存块释放。
举例:
#include<stdio.h> #include<malloc.h> intmain() { char*p; p=(char*)malloc(100); if(p) printf("MemoryAllocatedat:%x/n",p); else printf("NotEnoughMemory!/n"); free(p); return0; }
二、函数声明(函数原型):
void*malloc(intsize);
说明:malloc向系统申请分配指定size个字节的内存空间。返回类型是void*类型。void*表示未确定类型的指针。C,C++规定,void*类型可以强制转换为任何其它类型的指针。这个在MSDN上可以找到相关的解释,具体内容如下:
mallocreturnsavoidpointertotheallocatedspace,orNULLifthereisinsufficientmemoryavailable.Toreturnapointertoatypeotherthanvoid,useatypecastonthereturnvalue.Thestoragespacepointedtobythereturnvalueisguaranteedtobesuitablyalignedforstorageofanytypeofobject.Ifsizeis0,mallocallocatesazero-lengthitemintheheapandreturnsavalidpointertothatitem.Alwayscheckthereturnfrommalloc,eveniftheamountofmemoryrequestedissmall.
三、malloc与new的不同点
从函数声明上可以看出。malloc和new至少有两个不同:new返回指定类型的指针,并且可以自动计算所需要大小。比如:
int*p; p=newint;//返回类型为int*类型(整数型指针),分配大小为sizeof(int);
或:
int*parr; parr=newint[100];//返回类型为int*类型(整数型指针),分配大小为sizeof(int)*100;
而malloc则必须由我们计算要字节数,并且在返回后强行转换为实际类型的指针。
int*p; p=(int*)malloc(sizeof(int));
第1、malloc函数返回的是void*类型,如果你写成:p=malloc(sizeof(int));则程序无法通过编译,报错:“不能将void*赋值给int*类型变量”。所以必须通过(int*)来将强制转换。
第2、函数的实参为sizeof(int),用于指明一个整型数据需要的大小。如果你写成:
int*p=(int*)malloc(1);
代码也能通过编译,但事实上只分配了1个字节大小的内存空间,当你往里头存入一个整数,就会有3个字节无家可归,而直接“住进邻居家”!造成的结果是后面的内存中原有数据内容全部被清空。
malloc也可以达到new[]的效果,申请出一段连续的内存,方法无非是指定你所需要内存大小。
比如想分配100个int类型的空间:
int*p=(int*)malloc(sizeof(int)*100);//分配可以放得下100个整数的内存空间。
另外有一点不能直接看出的区别是,malloc只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。
除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。
四、动态申请数组
申请一维数组
一维数组的数组名可以看成数组起始元素的首地址,因此我定义一个int*arr的指针,分配n个大小的int型空间,写法如下:
#include<stdio.h> #include<stdlib.h> intmain(void) { intn,*arr; while(scanf("%d",&n)!=EOF){ arr=(int*)malloc(sizeof(int)*n); } return0; }
申请二维数组
二维数组的数组名是其所有一维数组的首地址,因为二维数组的数组名是指针的指针,因为我定义一个row行column列的二维数组,写法如下:
#include<stdio.h> #include<stdlib.h> intmain(void) { inti,row,column,**arr; while(scanf("%d%d",&row,&column)!=EOF){ arr=(int**)malloc(sizeof(int*)*row);//分配所有行的首地址 for(i=0;i<row;i++){//按行分配每一列 arr[i]=(int*)malloc(sizeof(int)*column); } free(arr); } return0; }
总结:
malloc()函数其实就在内存中找一片指定大小的空间,然后将这个空间的首地址范围给一个指针变量,这里的指针变量可以是一个单独的指针,也可以是一个数组的首地址,这要看malloc()函数中参数size的具体内容。我们这里malloc分配的内存空间在逻辑上连续的,而在物理上可以连续也可以不连续。对于我们程序员来说,我们关注的是逻辑上的连续,因为操作系统会帮我们安排内存分配,所以我们使用起来就可以当做是连续的。