一.结构体赋值问题
如果结构体内部有指针指向内存,那么结构体p1=结构体p2会造成两个问题
1.该指针可能会被重复释放两次导致崩溃
2.p1指针指向的内存可能存在泄漏
所以,应该手动控制赋值过程
二.结构体包含一级指针
//
// main.c
// cdemo
//
// Created by liyongkai on 2021/6/6.
//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char *name;
int age;
};
//获取包含结构体的数组的指针
struct Person** getStructPerson() {
struct Person **temp = malloc(sizeof(struct Person *) * 3);
for (int i = 0; i < 3; i ++) {
struct Person *person = malloc(sizeof(struct Person));
person->name = malloc(sizeof(char) * 64);
sprintf(person->name, "Name_%d", i);
person->age = i + 10;
temp[i] = person;
}
return temp;
}
void printPerson(struct Person **p) {
if (p == NULL) return;
for (int i = 0; i < 3; i ++) {
struct Person *person = *(p+i);
printf("name is:%s age is:%d\n",person->name,person->age);
}
}
void freeSpace(struct Person **p) {
if (p == NULL) return;
for (int i = 0; i < 3; i ++) {
struct Person *person = p[i];
if (person == NULL) continue;
if (person->name != NULL) {
free(person->name);
person->name = NULL;
}
free(person);
person = NULL;
}
free(p);
p = NULL;
}
int main(int argc, const char * argv[]) {
struct Person **p = NULL;
p = getStructPerson();
printPerson(p);
// name is:Name_0 age is:10
// name is:Name_1 age is:11
// name is:Name_2 age is:12
//释放内存
freeSpace(p);
return 0;
}
三.结构体包含二级指针
//
// main.c
// cdemo
//
// Created by liyongkai on 2021/6/6.
//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
typedef struct StudentStruct {
char *name;
}Student;
typedef struct TeacherStruct {
char *name;
Student **sp;
}Teacher;
Student ** createStudnets() {
Student **sp = malloc(sizeof(Student) * 3);
for (int i = 0; i < 3; i ++) {
Student *student = malloc(sizeof(Student));
student->name = malloc(sizeof(char) * 64);
sprintf(student->name, "studentName:%d",i);
sp[i] = student;
}
return sp;
}
Teacher **createTeachers() {
Teacher **tp = malloc(sizeof(Teacher *) * 3);
for (int i = 0; i < 3; i ++) {
Teacher *teacher = malloc(sizeof(Teacher));
teacher->name = malloc(sizeof(char) * 64);
sprintf(teacher->name, "teacherName:%d",i);
Student **sp = createStudnets();
teacher->sp = sp;
*(tp+i) = teacher;
}
return tp;
}
void printAll(Teacher **tp) {
for (int i = 0; i < 3; i++) {
Teacher *teacher = *(tp + i);
for (int i = 0; i < 3; i ++) {
Student *student = *(teacher->sp + i);
printf("teacher的名字:%s,他的学生的名字是%s\n",teacher->name,student->name);
}
}
}
void freeAll(Teacher **tp) {
for (int i = 0; i < 3; i++) {
Teacher *teacher = *(tp + i);
if (teacher == NULL) continue;
for (int i = 0; i < 3; i ++) {
Student *student = *(teacher->sp + i);
if (student == NULL) continue;
free(student->name);
student->name = NULL;
free(student);
student = NULL;
}
free(teacher->sp);
teacher->sp = NULL;
if (teacher->name != NULL) {
free(teacher->name);
teacher->name = NULL;
}
free(teacher);
teacher = NULL;
}
}
int main(int argc, const char * argv[]) {
Teacher **tp = createTeachers();
printAll(tp);
freeAll(tp);
if (tp != NULL) {
free(tp);
tp = NULL;
}
return 0;
}
四.结构体偏移量
struct Teacher{
char a;
int b;
};
int main(int argc, const char * argv[]) {
struct Teacher teacher = {
'a',
20
};
//通过结构体偏移拿到b的值
char*pChar = (char*)&teacher; //强转为指向char类型的指针
int *pInt = (int *)(pChar+4); //因为结构体内存对齐的原因,从第4位开始,然后强转为指向int类型的指针
printf("%d\n",*pInt); //结果为20
//或者直接这样写
printf("%d\n", *(((int*)&teacher) +1)); // 20
return 0;
}
五.结构体内存对齐
内存对齐的原因:为了效率,牺牲空间节约时间。
网友评论