结构体的对齐方式以及结构体嵌套指针的使用方法
结构体数组
定义结构体数组的方法很简单,同定义结构体变量是一样的,只不过将变量改成数组。或者说同前面介绍的普通数组的定义是一模一样的,如: struct STUDENT stu[10];
这就定义了一个结构体数组,共有 10 个元素,每个元素都是一个结构体变量,都包含所有的结构体成员。 #define _CRT_SECURE_NO_WARNINGS #include #include #include #include typedef struct Teacher { char name[50]; //char* name; int age; }Teacher; int main() { Teacher a[3] = { {"a",11}, {"b",12}, {"c",13} }; //静态 Teacher a2[3] = { "aa",13,"bb",12 ,"cc",13}; for (int i = 0; i < 3; i++) { printf("%s, %d ", a2[i].name, a2[i].age); } int b[3] = { 0 }; int* pB = (int*)malloc(3 * sizeof(int)); free(pB); //Teacher p[3] Teacher* p = (Teacher*)malloc(3 * sizeof(Teacher)); if (p==NULL) { return -1; } char buf[50]; for (int i = 0; i < 3; i++) { sprintf(buf, "name%d%d%d", i, i, i); strcpy(p[i].name, buf); p[i].age = 20 + i; } for (int i = 0; i < 3; i++) { printf("第%d个:%s,%d ", i + 1, p[i].name, p[i].age); } printf(" "); if (p!=NULL) { free(p); p = NULL; } return 0; }结构体嵌套一级指针#define _CRT_SECURE_NO_WARNINGS #include #include #include #include typedef struct Teacher { char* name; int age; }Teacher; showTeacher(Teacher* q, int n) { for (int i = 0; i < n; i++) { printf("%s ,%d ", q[i].name, q[i].age); } } freeTeacher(Teacher* q, int n) { for (int i = 0; i < n; i++) { if (q[i].name != NULL) { free(q[i].name); q[i].name = NULL; } } if (q != NULL) { free(q); q = NULL; } } Teacher* getMem( int n) { Teacher*q = (Teacher*)malloc(sizeof(Teacher)); //Teacher q[3] char buf[30]; for (int i = 0; i < n; i++) { q[i].name = (char*)malloc(30); sprintf(buf, "name%d%d%d", i, i, i); strcpy(q[i].name, buf); q[i].age = 20 + i; } return q; } Teacher* getMem2(Teacher**temp,int n) { if (temp==NULL) { return -1; } Teacher* q = (Teacher*)malloc(sizeof(Teacher)); //Teacher q[3] char buf[30]; for (int i = 0; i < n; i++) { q[i].name = (char*)malloc(30); sprintf(buf, "name%d%d%d", i, i, i); strcpy(q[i].name, buf); q[i].age = 20 + i; } *temp = q; return 0; } int main() { char* name = NULL; name = (char*)malloc(30); strcpy(name, "aa"); printf("name=%s ", name); if (name!=NULL) { free(name); name = NULL; } //1 Teacher t; t.name = (char*)malloc(30); strcpy(t.name, "s"); t.age = 22; printf("name=%s age=%d ", t.name, t.age); if (t.name!=NULL) { free(t.name); t.name = NULL; } //2 Teacher* p = NULL; p = (Teacher*)malloc(sizeof(Teacher)); p->name = (char*)malloc(30); strcpy(p->name, "ss"); p->age = 22; printf("name=%s age=%d ", p->name, p->age); if (p->name!=NULL) { free(p->name); p->name = NULL; } if (p!=NULL) { free(p); p = NULL; } //3 Teacher* q = NULL; //q = getMem(3); int ret = 0; ret = getMem2(&q, 3); if (ret!=NULL) { return ret; } showTeacher(q,3); freeTeacher(q, 3); p = NULL; return 0; }结构体嵌套二级指针#define _CRT_SECURE_NO_WARNINGS #include #include #include #include //一个导师有若干学生 typedef struct Teacher { int age; char**stu;//二维内存 }Teacher; //n1老师个数 n2每个老师带的学生数 int createTeacher(Teacher** temp, int n1,int n2) { if (temp==NULL) { return -1; } Teacher* q = (Teacher*)malloc(sizeof(Teacher) * n1); //Teacher q[3] for (int i = 0; i < n1; i++) { //q[i].stu //(q+i)->stu q[i].stu = (char**)malloc(sizeof(char*)*n2); //char* stu[3] for (int j = 0; j < n2; j++) { q[i].stu[j] = (char*)malloc(30); char buf[30]; sprintf(buf, "name%d%d%d%d", i, i, j, j); strcpy(q[i].stu[j], buf); } q[i].age = 20 + i; } *temp = q; return 0; } void showTeacher(Teacher* q, int n1, int n2) { if (q=NULL) { return; } for (int i = 0; i < n1; i++) { printf("[age=%d] ", q[i].age); for (int j = 0; j < n2; j++) { printf("%s, ", q[i].stu[j]); } printf(" "); } printf(" "); } void sortTeacher(Teacher*p,int n) { if (p==NULL) { return; } Teacher temp; for (int i = 0; i < n-1; i++) { for (int j = i+1; j < n; j++) { if (p[i].age < p[j].age)//降序 { temp = p[i]; p[i] = p[j]; p[j] = temp; } } } } void freeTeacher(Teacher** temp, int n1, int n2) { if (temp==NULL) { return; } Teacher* q = *temp; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (q[i].stu[j] != NULL) { free(q[i].stu[j]); q[i].stu[j] = NULL; } } if (q[i].stu != NULL) { free(q[i].stu); q[i].stu = NULL; *temp = NULL; } } if (q != NULL) { free(q); q = NULL; } } int main() { char** name = NULL; //char* name[3] int n = 3; name = (char**)malloc(sizeof(char*) * 3); for (int i = 0; i < n; i++) { name[i] = (char*)malloc(30); strcpy(name[i], "aaa"); } for (int i = 0; i < n; i++) { printf("%s ", name[i]); } for (int i = 0; i < n; i++) { if (name[i]!=NULL) { free(name[i]); name[i] = NULL; } } if (name!=NULL) { free(name); name = NULL; } //1 Teacher t; //t.stu[3] //char* t.stu[3] int n = 3; t.stu = (char**)malloc(sizeof(char*) * 3); for (int i = 0; i < n; i++) { t.stu[i] = (char*)malloc(30); strcpy(t.stu, "aaa"); } for (int i = 0; i < n; i++) { printf("%s ",t.stu[i]); } for (int i = 0; i < n; i++) { if (t.stu[i] != NULL) { free(t.stu[i]); t.stu[i] = NULL; } } if (t.stu != NULL) { free(t.stu); t.stu = NULL; } //2 Teacher* p = NULL; //p->stu[3] p = (Teacher*)malloc(sizeof(Teacher)); //char* t.stu[3] int n = 3; p->stu = (char**)malloc(sizeof(char*) * 3); for (int i = 0; i < n; i++) { p->stu[i] = (char*)malloc(30); strcpy(p->stu, "aaa"); } for (int i = 0; i < n; i++) { printf("%s ", p->stu[i]); } for (int i = 0; i < n; i++) { if (p->stu[i] != NULL) { free(p->stu[i]); p->stu[i] = NULL; } } if (p->stu != NULL) { free(p->stu); p->stu = NULL; } if (p!=NULL) { free(p); p = NULL; } //3 Teacher* q = NULL; int ret = 0; ret = createTeacher(&q, 3,3); //Teacher* q[3] //q[i].stu[3] printf("排序前 "); showTeacher(q, 3, 3); sortTeacher(q, 3); printf("排序后 "); showTeacher(q,3,3); freeTeacher(&q, 3, 3); return 0; } 结构体的深拷贝与浅拷贝#define _CRT_SECURE_NO_WARNINGS #include #include #include #include typedef struct Teacher { char* name; int age; }Teacher; //结构体中嵌套指针,而且动态分配空间 //同类型结构体变量赋值 //结构体成员指针变量指向同一块内存 int main() { Teacher t1; t1.name = (char*)malloc(30); strcpy(t1.name, "tom"); t1.age = 22; Teacher t2; t2 = t1; //深拷贝,人为增加内容,重新拷贝一下 t2.name= (char*)malloc(30); strcpy(t2.name, t1.name); printf("[t2]%s,%d ", t2.name, t2.age); if (t1.name!=NULL) { free(t1.name); t1.name = NULL; } //重复释放 //浅拷贝:t2的值还指向同一块内存 t1.name t1释放后t2又释放 导致出现错误 if (t2.name != NULL) { free(t2.name); t2.name = NULL; } return 0; } 结构体的对齐方式
结构体的对齐公式:
记住以下这些规则,把结构体往里面套就可以了。结构体对齐的原则就是牺牲空间的方式来减少时间的消耗,空间用完还可以复用,而时间过去了就再也不会回来了。 以 #pragma pack(x) 中 x 的大小和结构中占用空间最大的成员做比较,取小值为 n(外对齐依据) 以 n 值和结构体每个成员比较,得到结果列表为 m[x] 根据每个成员的大小依次向内存中填充数据,要求填充 成员的起始地址 减去 构体起始地址 的差都可以整除 m[x] ,如不能整除则向后移动,直到可以整除再填充成员到内存(内对齐依据) 当全部成员填充完毕后所占用的字节若不能整除 n,则扩充内存到可以整除 n 为止。
举个例子:
在这个例子中struct data的大小为8个字节。