http://blog.csdn.net/Bixiwen_liu/article/details/53610952
这几天把C语言巩固了一下,作为一门最基本的编程语言,C语言还是相当基础和非常重要的,个人认为C语言还是很有必要学好吃透的。
今天写的话题是结构体结构体中一级指针和二级指针的创建与释放,以一个例子来说明,笔者这里自己敲得代码,虽然用C语言几年了,但是有的东西还是会遗忘。笔者敲代码过程中也是有bug出现的,经过调试也找到了bug所在,不得不说,巩固也是很重要的。而结构体作为C语言一部分也是很重要的,指针作为C语言的半壁江山也保持着其重要地位。代码不是很长,但里面有很多细节的考虑,特别是一级指针和二级指针的内存的申请和释放。
代码的主要表达是:有三个老师,每个老师都有属性名字,年龄,别名,编号,以及有三个学生名字。老师名字(name)的内存分配是在栈区,别名(alisname)和学生名(stuname)的内存分配是在堆区。个人认为C语言的内存四区(栈区,堆区,全局区,代码区)很重要,所以喜欢从内存四区的角度看代码,对理解C语言的本质是重要,也是理解bug所在的重要原因。
下面是示例代码:
[cpp] view plain copy
- // 结构体 示例
- #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;
- }