原本malloc()函数 返回值类型为 void *, 调用格式为:malloc(size),size的类型为unsigned int ,表示用来分配size个字节的存储区。 因为malloc函数的返回的地址为void *, 在调用函数时,必须用强制类型转换将其转换为所需要的类型。括号中的 * 号代表返回的是指针类型的(分配类型 *)malloc(分配元素个数 *sizeof(分配类型))函数包含于stdlib.h和malloc.h中,当指定大小的内存区分配成功则返回指向该区域的指针,否则返回NULL。通过调用malloc函数所分配的动态存储单元中没有确定的初值,这个存储单元也没有名字,只能靠指针来引用它。例如:char *Ptr = NULL; Ptr = (char *)malloc(100 * sizeof(char)); 又如: int *pi; float *pf; pi=(int *)malloc(2); pf=(float *)malloc(4);下面是引用一下百度百科的介绍:
函数简介
原型
externvoid*malloc(unsignedintnum_bytes);
头文件
在TC2.0中可以用malloc.h或alloc.h(注意:alloc.h与malloc.h的内容是完全一致的),而在VisualC++6.0中可以用malloc.h或者stdlib.h。
功能
分配长度为num_bytes字节的内存块
返回值
如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。
说明
关于该函数的原型,在旧的版本中malloc返回的是char型指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。
名称解释
malloc的全称是memoryallocation,中文叫动态内存分配,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。
相关函数
calloc、realloc、free、_alloca
函数声明
全名
void*malloc(size_tsize);
备注
void*表示未确定类型的指针,void*可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者...)
与new的区别
从本质上来说,malloc(Linux上具体实现可以参考manmalloc,glibc通过brk()&mmap()实现)是libc里面实现的一个函数,如果在sourcecode中没有直接或者间接include过stdlib.h,那么就会报出error:‘malloc’wasnotdeclaredinthisscope。如果生成了目标文件(假定动态链接malloc),如果运行平台上没有libc(Linux平台,手动指定LD_LIBRARY_PATH到一个空目录即可),或者libc中没有malloc函数,那么会在运行时(Run-time)出错。new则不然,是c++的关键字,它本身不是函数。new不依赖于头文件,c++编译器就可以把new编译成目标代码(g++4.6.3会向目标中插入_Znwm这个函数,另外,编译器还会根据参数的类型,插入相应的构造函数)。
在使用上,malloc和new至少有两个不同:new返回指定类型的指针,并且可以自动计算所需要大小。比如:
1 2 3 | int*p; p=newint; //返回类型为int*类型(整数型指针),分配大小为sizeof(int); |
或:
1 2 3 | int*parr; parr=newint[100]; //返回类型为int*类型(整数型指针),分配大小为sizeof(int)*100; |
而malloc则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针。
1 2 3 4 5 6 7 | 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),用于指明一个整型数据需要的大小。
在Linux中可以有这样:malloc(0),这是因为Linux中malloc有一个下限值16Bytes,注意malloc(-1)是禁止的;
但是在某些系统中是不允许malloc(0)的。在规范的程序中我们有必要按照这样的格式去使用malloc及free:
1 2 3 4 5 6 7 8 9 10 | type*p; if(NULL==(p=(type*)malloc(sizeof(type)))) { perror("error..."); exit(1); } ... free(p); p=NULL; |
malloc也可以达到new[]的效果,申请出一段连续的内存,方法无非是指定你所需要内存大小。
比如想分配100个int类型的空间:
1 2 | int*p=(int*)malloc(sizeof(int)*100); //分配可以放得下100个整数的内存空间。 |
另外有一点不能直接看出的区别是,malloc只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。
除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。
对其做一个特例补充
1 2 3 4 5 | char*ptr; if((ptr=(char*)malloc(0))==NULL) puts("Gotanullpointer"); else puts("Gotavalidpointer"); |
此时得到的是Gotavalidpointer。把0赋给malloc能得到一个合法的指针。
memset 介绍:
需要添加的头文件:
memory.h
或者 string.h
函数原型
void *memset(void *s,int value, size_t num);
使用时的注意点:
1. memset函数是以字节为单位进行初始化的,初始化以s为首地址的num个字节数,
num代表的是字节数目,表示把从地址s开始的每个字节都初始化为
value对应的ascll码来存放。
2. 上面写的返回类型 以及括号中 *s 的类型都是 void ,其实这是
根据具体情况修改的,如果 s 定义成指向整数数组的指针,那么上面
可以写为 int *memset(int *s,int ch, size_t num); 返回的是指向s
的指针。
3. 使用memset函数来初始化数组或者结构体比其他初始化方法更快一点
例子:
char str[20];
memset(str,0,sizeof(char)*20) 或者 memset(str,0,20)
上面这两种初始化方法是一致的
注意上面的是字符型数组 char str[20]
如果现在换成 整型数组 即 int num[20], 该如何对这个数组赋初值呢
例: int num[20];
memset(num,1,20*4) ; // 或者 memset(num,1,20*sizeof(int)) ;
用上面这种形式对 整型数组num 赋初值行吗??
答案是否定的。
原因还是前面介绍过的,因为memset()是按字节赋初值的,
上面的语句表示把 20*4 个字节全都赋值为 1 ,每个int 占用4个字节,
也就是每个int的内容如下:
00000001000000010000000100000001
这样用16进制表示为0x01010101,用十进制为 16843009 ,而不再是1。
所以建议用memset来对字符型数组赋值,因为这样能达到想要的目的。
当然,如果你相对整型数组全部赋初值为0,那么上面的语句就能很好
的满足我们的要求了。
补充:
1. memset(num,1,20*sizeof(int)) ;
memset(num,1,20*4) ;
memset(num,1,sizeof(num)) ;
上面这三条语句的效果是等价的,第三个参数的内容就是计算数组num的
字节数。
2. 用memset()来对整型数组的所有值赋值为 -1,也能达到效果,
即,memset(num,-1,20*4) ; 这条语句能使num[]的20个元素值都为-1.