C语言:结构体中一级指针和二级指针的创建与释放示例

这几天把C语言巩固了一下,作为一门最基本的编程语言,C语言还是相当基础和非常重要的,个人认为C语言还是很有必要学好吃透的。

今天写的话题是结构体结构体中一级指针和二级指针的创建与释放,以一个例子来说明,笔者这里自己敲得代码,虽然用C语言几年了,但是有的东西还是会遗忘。笔者敲代码过程中也是有bug出现的,经过调试也找到了bug所在,不得不说,巩固也是很重要的。而结构体作为C语言一部分也是很重要的,指针作为C语言的半壁江山也保持着其重要地位。代码不是很长,但里面有很多细节的考虑,特别是一级指针和二级指针的内存的申请和释放。

代码的主要表达是:有三个老师,每个老师都有属性名字,年龄,别名,编号,以及有三个学生名字。老师名字(name)的内存分配是在栈区,别名(alisname)和学生名(stuname)的内存分配是在堆区。个人认为C语言的内存四区(栈区,堆区,全局区,代码区)很重要,所以喜欢从内存四区的角度看代码,对理解C语言的本质是重要,也是理解bug所在的重要原因。

下面是示例代码:


// 结构体 示例
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

typedef struct Teacher // 定义一个结构体,名称为Teacher
{
	char name[64];
	int age;
	char *alisname;//别名
	char **stuname;
	int id;
}Teacher;

int createTeacher(Teacher **pT, int num)
{
	int i = 0;
	int j = 0;
	int ret = 0;
	Teacher *tmp = NULL;

	tmp = (Teacher *)malloc(num * sizeof(Teacher));
	if (tmp == NULL)
	{
		ret = -1;
		printf("malloc err: %d\n",ret);
		return ret;
	}
	memset(tmp, 0, num * sizeof(Teacher));

	for (i = 0; i < num; i++)
	{
		char **myp = NULL;
		
		//先创建一级指针
		tmp[i].alisname = (char *)malloc(60);
		if ( tmp[i].alisname == NULL)
		{
			ret = -2;
			printf("malloc tmp[i].alisname err: %d\n",ret);
			return ret;
		}

		//再创建二级指针
		myp = (char **)malloc(3 * sizeof(char *));
		if (myp == NULL)
		{
			ret = -3;
			return ret;
		}
		for (j = 0; j < 3; j++)
		{
			myp[j] = (char *)malloc(60);
			if (myp[j] == NULL)
			{
				ret = -4;
				return ret;
			}
		}
		tmp[i].stuname = myp;
	}

	*pT = tmp;
	return ret;
}

int printTeacherandStu(Teacher *p, int num)
{
	int i = 0;
	int j = 0;
	int ret = 0;
	Teacher *tmp = NULL;

	if (p == NULL)
	{
		ret = -1;
		printf("p is null : %d\n",ret);
		return ret;
	}
	tmp = p;

	for (i = 0; i < num; i++)
	{
		char **myp = NULL;
		
		printf("teacher name: %s\n",tmp[i].name);
		printf(" teacher alisname: %s\n",tmp[i].alisname);

		printf("  student's name:  ");
		myp = tmp[i].stuname;
		for (j = 0; j < 3; j++)
		{
			printf("%s  ",myp[j]);
		}
		printf("\n");	
	}
	return ret;

}

void FreeTeacher(Teacher *p, int num)
{
	int i = 0;
	int j = 0;
	Teacher *tmp = NULL;

	tmp = p;

	for(i = 0; i < num; i++)
	{
		char **myp = NULL;
		//先释放以及指针
		if (tmp[i].alisname != NULL)
		{
			free(tmp[i].alisname);
		}

		//再释放二级指针
		if (tmp[i].stuname != NULL)
		{
			myp = tmp[i].stuname;
			for (j = 0; j < 3; j++)
			{
				if (myp[j] != NULL)
				{
					free(myp[j]);
				}
			}
			free(myp);
			tmp[i].stuname = NULL;
		}	
	}
	free(tmp);
}

int main()
{
	int ret = 0;
	int i = 0;
	int j = 0;
	int num = 3;
	Teacher *pArray = NULL;

	ret = createTeacher(&pArray, num);
	if (ret != 0)
	{
		printf("func createTeacher() err: %d\n",ret);
		return ret;
	}

	for (i = 0; i < num; i++)
	{
		printf("\nplease input teacher's name:");
		scanf("%s",pArray[i].name);

		printf("\n please input teacher's age:");
		scanf("%d",&(pArray[i].age));

		printf("\n please input teacher's alsname:");
		scanf("%s",pArray[i].alisname);

		for (j = 0; j < 3; j++)
		{
			printf("\n  please input student name:");
			scanf("%s",pArray[i].stuname[j]);
		}
	}

	ret = printTeacherandStu(pArray, num);
	if (ret != 0)
	{
		ret = -2;
		printf("func printTeacherandStu() err: %d\n",ret);
		return ret;
	}

	FreeTeacher(pArray, num);
	return 0;
}


 
具体详细细节就不讨论了,不懂的可以问,下面是运行结果: 



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Bixiwen_liu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值