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;
}