|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
1、结构体嵌套一级、二级指针
知识点:1.对于创建内存空间的指针,不能向他指向的内存空间写值。
2.malloc申请的空间在结束时需要手工释放,malloc怎么申请的 就要怎么释放;即只能拿到malloc返回的地址才能去释放。
3. malloc申请的内存空间只能够被释放一次,不允许多次释放
熟悉下面这个模型(内存的申请、建立和释放方法):
- #include "stdio.h"
- #include "stdlib.h"
- #include "string.h"
- // 结构体套一级、二级指针
- struct Teacher
- {
- char name[64];
- char *a_name;
- int age;
- char **stuname;
- };
- //打印
- void printfArray(struct Teacher *pArray, int count)
- {
- int i = 0, j = 0;
- for (i = 0; i < count; i++)
- {
- printf("\n%d ", pArray[i].age);
- printf("%s ", pArray[i].name);
- printf("%s ", pArray[i].a_name);
- for (j = 0; j < 3; j++)
- {
- printf("%s ", pArray[i].stuname[j]);
- }
- }
- }
- //排序
- void sortArray(struct Teacher *pArray, int count)
- {
- int i = 0, j = 0;
- struct Teacher tmp;
- for (i = 0; i < count; i++)
- {
- for (j = i + 1; j < count; j++)
- {
- if (pArray[i].age < pArray[j].age)
- {
- tmp = pArray[i];
- pArray[i] = pArray[j];
- pArray[j] = tmp;
- }
- }
- }
- }
- // 手工创建结构体数组
- struct Teacher * createTArray1(int count)
- {
- int i = 0, j = 0;
- struct Teacher*p1 = (struct Teacher *)malloc(count * sizeof(struct Teacher));
- if (p1 == NULL)
- {
- return NULL;
- }
- for (i = 0; i < count; i++)
- {
- memset(&p1[i], 0, sizeof(struct Teacher)); // 给申请的内存空间,每个字节赋0
- memset(p1+i, '0', sizeof(struct Teacher)); // 和上面等价
- p1[i].a_name = (char*)malloc(128 * sizeof(char)); // 开辟空间给a_name
- memset(p1[i].a_name, 0, 128 * sizeof(char)); //为自己开辟的空间赋初值
- //给stuname 手工打造一个二维内存空间
- {
- char **p2 = (char**)malloc(3 * sizeof(char*));
- for (j = 0; j < 3; j++)
- {
- p2[j] = malloc(128 * sizeof(char));
- memset(p2[j], 0, 128 * sizeof(char));
- }
- p1[i].stuname = p2;
- }
- }
- return p1;
- }
- // 释放创建的空间
- void freeTArray(struct Teacher * tArray, int num)
- {
- int i = 0;
- if (tArray == NULL)
- {
- return;
- }
- // 释放 为*a_name申请的空间
- for (i = 0; i < num; i++)
- {
- if (tArray[i].a_name != NULL) //为什么这里需要释放
- {
- free(tArray[i].a_name);
- }
- // 释放 为**stuname申请 的手工二维空间
- if (tArray[i].stuname != NULL)
- {
- int i1 = 0, j1 = 0;
- for (i1 = 0; i1 < 3; i1++)
- {
- if (tArray[i].stuname[i1] != NULL)
- {
- free(tArray[i].stuname[i1]);
- }
- }
- free(tArray[i].stuname);
- }
- // malloc怎么申请的 就要怎么释放;只能拿到malloc返回的地址才能去释放啦
- /* if (tArray[i].name != NULL) //这个地方需要自己释放吗?(不需要,结构图是一块申请的,要一块释放)
- {
- free(tArray[i].name);
- }
- */
- }
- if (tArray != NULL)
- {
- free(tArray);
- tArray = NULL; //垃圾话语
- }
- }
- void main()
- {
- int i = 0, j = 0;
- struct Teacher *pArray = createTArray1(3);
- if (pArray == NULL)
- {
- return;
- }
- //这里是结构体数组,tArray是首元素的地址,他的类型是首元素的类型,struct Teacher *;
- //tArray[0]是第一个结构体的变量名
- struct Teacher tArray[10];
- for (i = 0; i < 3; i++)
- {
- printf("\n请输入age:");
- scanf("%d", &pArray[i].age);
- printf("\n请输入name:");
- scanf("%s", pArray[i].name);
- printf("\n请输入a_name:");
- scanf("%s", pArray[i].a_name);
- char **p2 = pArray[i].stuname;
- for (j = 0; j < 3; j++)
- {
- printf("\n请输入学生的名字:");
- scanf("%s", p2[j]);
- }
- }
-
- printf("排序之前:\n");
- printfArray(pArray, 3);
- sortArray(pArray, 3);
- printf("\n排序之后:\n");
- printfArray(pArray, 3);
- freeTArray(pArray, 3);
- system("pause");
- }
复制代码
2、深浅copy
浅拷贝:指的是在进行结构体的拷贝时,由于结构体中有带内存块的指针变量,而拷贝时只是进行单纯的赋值操作,导致被复制的结构体所挂内存的丢失或没被创建。
深拷贝:即在拷贝时避免的结构体内指针所挂内存块旳丢失或未创建。
浅拷贝容易造成内存的多次释放和内存的泄露。
代码示例:
- #include "stdio.h"
- #include "stdlib.h"
- #include "string.h"
- struct AdTeacher
- {
- char name[64];
- char *a_name;
- int age;
- };
- // 手工创建结构体数组
- struct AdTeacher * createTArray2(int count)
- {
- int i = 0, j = 0;
- struct AdTeacher*p1 = (struct AdTeacher *)malloc(count * sizeof(struct AdTeacher));
- if (p1 == NULL)
- {
- return NULL;
- }
- for (i = 0; i < count; i++)
- {
- memset(&p1[i], 0, sizeof(struct AdTeacher));
- memset(p1 + i, '0', sizeof(struct AdTeacher)); // 和上面等价
- p1[i].a_name = (char*)malloc(128 * sizeof(char)); // 开辟空间给a_name
- memset(p1[i].a_name, 0, 128 * sizeof(char)); //为自己开辟的空间赋初值
- }
- return p1;
- }
- // 释放创建的空间
- void freeTArray2(struct AdTeacher * tArray, int num)
- {
- int i = 0;
- if (tArray == NULL)
- {
- return;
- }
- // 释放 为*a_name申请的空间
- for (i = 0; i < num; i++)
- {
- if (tArray[i].a_name != NULL) //为什么这里需要释放
- {
- free(tArray[i].a_name);
- }
- }
- if (tArray != NULL)
- {
- free(tArray);
- tArray = NULL; //垃圾话语
- }
- }
- // 深拷贝
- void deepCopy(struct AdTeacher *from, struct AdTeacher *to)
- {
- memcpy(to, from, sizeof(struct AdTeacher));
- to->a_name = (char *)malloc(128);
- strcpy(to->a_name, from->a_name);
- }
- void main()
- {
- int i = 0;
- //struct AdTeacher t1;
- //struct AdTeacher t2;
- struct AdTeacher* p1 = createTArray2(1);
- struct AdTeacher* p2 = createTArray2(1);
- printf("\n请输入age:");
- scanf("%d", &(p1[0].age));
- printf("\n请输入name:");
- scanf("%s", p1->name);
- printf("\n请输入a_name:");
- scanf("%s", p1[0].a_name);
- //浅拷贝
- // (*p2) = (*p1);
- //编译器机械的=赋值,浅拷贝, 会导致p2和p1中的*a_name同时都指向p1中*a_name申请的内存空间
- //导致p1中*a_name在释放时释放两次,而p2中*a_name没有被释放。
- //自建函数来实现深拷贝
- deepCopy(p1, p2);
- freeTArray2(p1, 1);
- freeTArray2(p2, 1);
- system("pause");
- }
复制代码
|
|