何时使用或何时不使用malloc函数?学数据结构有感

Posted hemengjita

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了何时使用或何时不使用malloc函数?学数据结构有感相关的知识,希望对你有一定的参考价值。

在学数据结构时,我们往往不太清楚在定义一个结构体指针时要不要使用malloc函数。 
例如以下的代码:

LINKLIST  *init linklist()
{
    LINKLIST *H=NULL;
    LINKLIST *S;
    int x;
    printf("请输入链表元素 或以-1结束输入")
    while(x!=-1)
    {
      s=(LINKLIST*)malloc(sizeof(LINKLIST));
      s->data=x;
      s->next=H;
      H=s;
      scanf(%d,&x);
    }
retrun H;
}

在定义结构体指针变量S时需要用到malloc函数 
而定义结构体指针变量H时则没有用到malloc函数 
S和H的区别所在是:H没有指向有效地内存地址,而S指向了有效地内存地址,因为S指向了有效地内存地址所以可以往S指向的内存地址里面写值:S->data=x;而在后来H指向的地址就是每一个新的S指向的地址:H=S; 


再举个例子

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;

 

 

为什么要?何时要?

  malloc()是动态内存分配函数,用来向系统请求分配内存空间。当无法知道内存具体的位置时,想要绑定真正的内存空间,就要用到malloc()函数。因为malloc只管分配内存空间,并不能对分配的空间进行初始化,所以申请到的内存中的值是随机的,经常会使用memset()进行置0操作后再使用。  

  与其配套的是free()当申请到的空间不再使用时,要用free()函数将内存空间释放掉,这样可以提高资源利用率,最重要的是----就是因为它可以申请内存空间,然后根据需要进行释放,才被称为“动态内存分配”! 

  

  比如在数据结构中定义图的邻接表存储时

//将邻接矩阵MG转换为邻接表AG
void MatToList(MGraph MG,ALGraph *&AG)
{
    int n=MG.vexnum;//n存放图节点个数,方便书写
    ArcNode *p;
    AG=(ALGraph *)malloc(sizeof(ALGraph));//【手动申请空间并初始化邻接表,必须进行malloc,否则程序不能执行!】
    for(int i=0;i<n;i++)
        AG->adjlist[i].firstarc=NULL; //习惯性,malloc完就初始化 如memset

    for(int i=0;i<n;i++)
        for(int j=n-1;j>=0;j--)//注意遍历顺序,【这会影响后面链表添加节点使用头插法还是尾插法!】
            if(MG.edges[i][j]!=0&&MG.edges[i][j]!=INF)
            {
                p=(ArcNode *)malloc(sizeof(ArcNode));
                p->adjvex=j;//弧头指向的节点
                p->weight=MG.edges[i][j];//弧的权
                p->nextarc=AG->adjlist[i].firstarc;//头插法添加节点,因为前面是节点数值大的往前遍历的,因此顺序正好是0-1-3!
                AG->adjlist[i].firstarc=p;
            }
    AG->n=n;
    AG->e=MG.arcnum;
}

 

malloc 和free的形象解释:

  malloc()函数实质体现在,它有一个可以将可用内存块连接成一个长长的列表的链表,这个链表就是所谓的空闲链表。调用malloc()函数时,它沿着连接表寻找一个大到可以满足用户请求要求的连续的内存块,然后将内存块一分为二,一块的大小与用户请求的内存大小相等,另一块就是剩下的内存块。接下来,它将用户申请的那块传递给用户,将另一块返回到连接表上(如果另一块有的话)。 

  调用free()函数的时候,它将用户想要释放的内存块链接到空闲链上。我们可以想到,最后的空闲链链接的内存空间一小块一块的块,如果这是用户申请分配一个较大的内存空间,那么空闲链上可能没有符合用户要求的内存块了,这个时候,malloc()函数请求延时,并开始在空闲链上翻箱倒柜的检查各内存块,对他们进行整理,将相邻的小内存块合并成较大的内存块。如果无法获得符合用于要求的内存空间,那么malloc()函数就会返回NULL,因此,调用malloc()函数的时候,一定要判断它的返回值是否为NULL。

参考

https://blog.csdn.net/wstz_5461/article/details/74356690?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control 

 








以上是关于何时使用或何时不使用malloc函数?学数据结构有感的主要内容,如果未能解决你的问题,请参考以下文章

何时使用 Malloc 而不是 New [重复]

了解何时需要 malloc():我在编译时知道 char * n 的长度,但似乎仍然需要 malloc()

何时将 malloc 用于 char 指针

iOS——使用工具来标记何时调用方法[或函数]?

何时在 clojure(或 lisp)中使用感叹号?

何时在 Swift 中使用全局变量