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