结构体

作者: 李永开 | 来源:发表于2021-07-24 14:13 被阅读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;
}

五.结构体内存对齐

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

相关文章

  • 结构体

    [toc] 结构体的定义方式 先定义结构体类型,再定义结构体变量 定义结构体类型的同时定义结构体变量 定义结构体类...

  • 【C语言笔记】<十九>结构体

    结构体的基本概念 结构体初始化 结构体的内存存储细节 结构体定义的方式 结构体类型的作用域 指向结构体的指针 结构...

  • C结构体和链表

    一,结构体变量定义及初始化 二,无名结构体 备注:无名结构体很少使用 三,宏定义结构体 四,结构体嵌套 五,结构体...

  • 结构体

    结构体定义* 结构体中的格式:* struch 结构体名* {* 结构体成员变量* }* 结构体中的特点* 1.结...

  • 结构体数组的定义

    结构体数组的定义 1、先定义结构体类型,再定义结构体数组 2、定义结构体类型的同时定义结构体数组 3、省略结构体类...

  • C#结构体,析构方法,跨程序访问

    结构体 结构体定义 结构体的语法格式: struct + 结构体名 { 结构体成员变量(相当于类中的字段) } 结...

  • 结构体

    结构体有名定义 无名定义 结构体嵌套定义 结构体内存对齐 结构体成员初始化 结构体变量引用 结构体的有名定义:直白...

  • 菜鸡学Swift3.0 13.结构体

    结构体 struct 是值类型 1.定义结构体 struct 结构体类型 { var 结构体属性:类型 ...} ...

  • 结构体

    结构体初识 结构体指针 结构体的匿名字段 结构体嵌套 Go语言中的OOP

  • C语言 第九章 结构体

    [TOC] 第九章结构体 结构体的定义 结构体定义2 指针表示结构体

网友评论

      本文标题:结构体

      本文链接:https://www.haomeiwen.com/subject/sgtsmltx.html