为什么要malloc()?何时要malloc()?如何使用malloc()?

各方评论:
malloc free 是C库函数
C++ 基本用不上
C ++ 改用new ,delete 运算符了
c++本来就不提倡使用malloc,而是用new,毕竟malloc只是内存分配,不管构造函数的调用。
当需要动态分配的空间的时候就要用到malloc了,原来的程序可能都是申请的局部变量,变量存储位置在栈上,使用malloc的变量空间在堆上,只返回空间指针,使用完成后要调用free函数。
比较常用的,动态数组(数组无法事先确定大小),链表节点内存的动态分配和释放,等等。
比如你在编译时不能确定数组的大小,需要动态分配。
再比如内存池需要管理内存,需要自行分配一片大的内存。

1.malloc是用来进行内存分配,事先不知道大小时
2.需要重新分配(增加)内存,前面最好用malloc分配,然后用realloc
3.分配较大内存时,因为栈空间有限
4.从函数返回结果时,由于生命周期的原因

函数原型: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是一个很好的习惯。

内存泄漏:

例1:

#include 
#include 
#define MAX 1000000
int main(void)
{
    int *a[MAX] = {NULL};
    int i;
    for(i=0;i

例2:

#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
   //如果malloc失败,可以得到一些log此处返回条件判断错误,应为:if(NULL == a)   
    if(!a)
    {
        perror("malloc");
        return -1;
    }
    sprintf(a,"%s","HelloWorld\n");//"HelloWorld\n"写入a指向的地址
    printf("%s\n",a);
    free(a);//释放掉使用的内存地址
    return 0;
}

再举个例子

LINKLIST *S;
S->data=x;
  • 以上这两句代码是不行的,因为S没有指向确切的地址,所以不能通过S来向它要指向的地址赋值;
  • 但是:
LINKLIST *S;
LINKLIST P;
S=&P;
S->data=x;
  • 是可以的,因为S指向P的地址,S->data=x;等同于p.data=x; (结构体的指针变量和实际变量调用元素的区别)

  • 而malloc的作用就类似以上代码的作用;但是不用再定义一个结构变量P,再让结构体指针变量S指向它的地址&P,而是直接使用malloc函数让结构体指针变量S指向一个确切的内存地址。

LINKLIST *s;
s=(LINKLIST*)malloc(sizeof(LINKLIST));
s->data=x;

再举一个简单的例子

//错误例子
int * i;
*i=1;  
//正确例子
int * i;
i=(int*)malloc(sizeof(int));
*i=1;    

未完待续。。。

你可能感兴趣的:(为什么要malloc()?何时要malloc()?如何使用malloc()?)