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