• 何时使用或何时不使用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 

  • 相关阅读:
    程序员需要看的书
    linux常见命令实践.
    数据库使用简单总结
    剑指offer【书】之简历抒写
    面试中自己项目和你应该问的问题环节总结
    Matlab近期用到的函数(持续更新)
    排序-快速排序算法
    系统运维-hub, repeater, switch, router初览
    C++基础-位运算
    排序-冒泡排序
  • 原文地址:https://www.cnblogs.com/hemengjita/p/14102347.html
Copyright © 2020-2023  润新知