结构体中有指针成员的逐层malloc 与 free

1、malloc的时候注意,如果结构体有结构体指针成员,malloc的时候需要逐层都进行malloc。

先malloc最外面的event_nodeP,才能访问到event_nodeP->dataP 和 event_nodeP->participantP,

再对这两个结构体指针成员进行malloc。

2、free:free(参数为malloc或者calloc等分配的指针),并且free之后给指针赋值NULL是为了后面再非法地访问这个已经成为空指针的指针变量,如果*NULL,会导致程序无法运行,提醒程序员出错了。

3、free的结构体指针中如果有成员是结构体指针的话,free的时候要先从里层free,否则如果先把外层free,里面的访问不到,不能进行free。如果先free了最外面一层的,再free里面的结构体指针malloc的空间,这样相当于犯了第二个错误:间接访问空指针(因为最外层的已经是NULL了)。

注:scene_result和上面的event_nodeP是一样的结构。

要先free participantP 和 datap 这两个结构体指针成员,把他们free掉,不能先free最外层的scene_result,否则就访问不到participantP 和 datap,不能对其free了,因此此时scene_result[i]->dataP 和 scene_result[i]->participantP 会让程序无法运行。

4、重点是要注意对于有结构体指针成员的这种结构体,malloc 和 free 的时候要注意正确的顺序。

5、对malloc的理解

23_结构体中包含另外一个结构体指针,为其进行二级malloc以及三级malloc(图解!!!)_HanLongXia的博客-CSDN博客_结构体中包含另一个结构体(这个文章要看)

当定义一个结构体指针变量之后,要么:(1)把已经存在的一个结构体的地址给到这个指针变量,让这个指针变量指向该结构体;(2)要么,为这个结构体malloc/calloc一块内存空间。

 malloc:相当于寻找到一块堆内存,把这块内存的首地址返回来给一个指针变量,使这个指针变量能够访问这块内存。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define _CRT_SECURE_NO_WARNINGS

typedef struct student
{
	int id;
	char *name;
}STU;

typedef struct tercher
{
	STU *s;
	char *name;
}TER;

void test01()
{
	TER *p = (TER *)malloc(sizeof(TER));			//一级
	p->name = (char *)malloc(sizeof(char)*128);		//二级
	p->s = (STU*)malloc(sizeof(STU));				//二级(结构体指针s记得也需要创建堆区)
	p->s->name = (char *)malloc(sizeof(char)*128);	//三级

	strcpy(p->name, "ubioo");
	p->s->id = 1400;
	strcpy(p->s->name, "sss");
	
	printf("%s %d %s\n", p->name, p->s->id, p->s->name);
	free(p->name);
	free(p->s->name);
    free(p->s);
	free(p);
}

int main()
{
	test01();
	return 0;
}

对其中语句的意思进行解读:

(①定义一个指向TER结构的变量)TER* p = (TER*)malloc(sizeof(TER));(②分配一块堆区域,获取首地址)

实际上完成的相当于有两个部分:

①定义了一个指向TER结构的变量p;②在内存中分配了一块堆区域,并将这块堆区域的地址给到变量p。如果不进行②的话,也应该是把一个TER结构体变量的地址给到p,只是这块地址对应的空间可能不是在堆中。

逐级malloc:就是说当有指针的时候,应该为结构体中的指针成员进行malloc,要么就是选择①的方式给人家指定出指向哪个结构体变量。

free:free的是堆中分配的空间,并不是把那块内存给销毁了,只是把那块内存的使用权释放出来了。否则如果不释放的话,根据malloc函数,会不断的在内存中寻找没有被占用的堆空间,如果每次只占用但是不释放,这样很有可能造成内存不足,程序不能运行。

----------------------------------------------------分割线---------------------------------------------------------------

判断某个条件是否满足,如果不满足,可以用return NULL来代替,那么此函数将会退出,继续直行之后的语句。NULL用%d打印,数值为1。注意,退出的是带有return NULL的函数,跳出函数后,剩下的语句继续直行,如果return NULL语句在main函数中,那么就是整个程序运行到return NULL就结束了。

#include <stdio.h>
#include <stdlib.h>

int Add(int a, int b)
{
	int d = 1;
	if(d == 1)
	{
		return NULL;,满足条件,return NULL后退出,没有计算2 + 3
	}
	
	return (a + b);
}

int main(void)
{
	int a = 1;
	
	int b = Add(2, 3);
	
	printf("%d\n",NULL);//NULL的值为0
	printf("b = %d\n",b);//b的取值实际上是NULL
	printf("hello");//跳出Add后,继续执行后面的语句。
	
	return 0;	
}

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小哇123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值