结构体

2021-07-24  本文已影响0人  李永开

一.结构体赋值问题

如果结构体内部有指针指向内存,那么结构体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;
}

五.结构体内存对齐

内存对齐的原因:为了效率,牺牲空间节约时间。

上一篇 下一篇

猜你喜欢

热点阅读