今日写程序,突然想到一个问题,为什么有时候不要malloc,为什么有时候要呢!好好查资料才了解到一些原理。
函数原型:void
*
malloc
(unsigned
int
num_bytes); //分配长度为num_bytes字节的内存块
返回值是void指针,void* 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者其他数据类型),可以通过类型强制转化转化为其他任意类型指针。如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。
为什么要?何时要?
malloc()是动态内存分配函数,用来向系统请求分配内存空间。当无法知道内存具体的位置时,想要绑定真正的内存空间,就要用到malloc()函数。因为malloc只管分配内存空间,并不能对分配的空间进行初始化,所以申请到的内存中的值是随机的,经常会使用memset()进行置0操作后再使用。
与其配套的是free(),当申请到的空间不再使用时,要用free()函数将内存空间释放掉,这样可以提高资源利用率,最重要的是----就是因为它可以申请内存空间,然后根据需要进行释放,才被称为“动态内存分配”!
malloc()函数实质体现在,它有一个可以将可用内存块连接成一个长长的列表的链表,这个链表就是所谓的空闲链表。调用malloc()函数时,它沿着连接表寻找一个大到可以满足用户请求要求的连续的内存块,然后将内存块一分为二,一块的大小与用户请求的内存大小相等,另一块就是剩下的内存块。接下来,它将用户申请的那块传递给用户,将另一块返回到连接表上(如果另一块有的话)。
调用free()函数的时候,它将用户想要释放的内存块链接到空闲链上。我们可以想到,最后的空闲链链接的内存空间一小块一块的块,如果这是用户申请分配一个较大的内存空间,那么空闲链上可能没有符合用户要求的内存块了,这个时候,malloc()函数请求延时,并开始在空闲链上翻箱倒柜的检查各内存块,对他们进行整理,将相邻的小内存块合并成较大的内存块。如果无法获得符合用于要求的内存空间,那么malloc()函数就会返回NULL,因此,调用malloc()函数的时候,一定要判断它的返回值是否为NULL。
如何使用?
int
*p;
p = (
int
*)
malloc
(
sizeof
(
int
) * 128);
//分配128个整型存储单元,并将这128个连续的整型存储单元的首地址存储到指针变量p中
double
*pd = (
double
*)
malloc
(
sizeof
(
double
) * 12);
//
分配12个double型存储单元,并将首地址存储到指针变量pd中
free(p); free(pd); p = NULL; pd = NULL; 指针用完赋值NULL是一个很好的习惯。 内存泄漏:例: #include <stdio.h>
#include <malloc.h>
#define MAX 1000000
int
main(
void
)
{
int
*a[MAX] = {NULL};
int
i;
for
(i=0;i<MAX;i++)
{
a[i]=(
int
*)
malloc
(MAX); //此处没有判断返回值
}
return
0;
}
例:#include "stdio.h"
#include "malloc.h"//malloc()函数被包含在malloc.h里面
int
main(
void
)
{
char
*a = NULL;
//声明一个指向a的char*类型的指针
a = (
char
*)
malloc
(100*
sizeof
(
char
));
//使用malloc分配内存的首地址,然后赋值给a
if
(!a)
//如果malloc失败,可以得到一些log, 此处返回条件判断错误,应为:if(NULL == a)
{
perror
(
"malloc"
);
return
-1;
}
sprintf
(a,
"%s"
,
"HelloWorld\n"
);
//"HelloWorld\n"写入a指向的地址
printf
(
"%s\n"
,a);
free
(a);
//释放掉使用的内存地址
return
0;
}