文章目录
一、结构体中嵌套二级指针
1、结构体中嵌套二级指针 类型声明
2、为 结构体内的二级指针成员 分配内存
3、释放 结构体内的二级指针成员 内存
二、完整代码示例
一、结构体中嵌套二级指针
1、结构体中嵌套二级指针 类型声明
结构体中 嵌套 二级指针 , 二级指针 可以使用 指针数组 / 二维数组 / 自定义二级指针内存 三种内存模型的任意一种 ;
此处选择的模型是 自定义二级指针内存 ;
代码示例 :
/** * @brief The Student struct * 定义 结构体 数据类型 , 同时为该结构体类型声明 别名 * 可以直接使用 别名 结构体变量名 声明结构体类型变量 * 不需要在前面添加 struct 关键字 */ typedef struct Student { // 声明变量时 , 会自动分配这 5 字节内存 // 赋值时 , 可以直接使用 = 赋值字符串 char name[5]; int age; int id; // 声明变量时 , 只会为 4 字节指针分配内存 // 具体的 字符串内存 需要额外使用 malloc 申请内存 // 赋值时 , 必须使用 strcpy 函数 , 向堆内存赋值 char *address; // 学生小组成员 , 由多个字符串组成 // 二级指针 , 指向多个 一级指针 // 每个 一级指针 指向 一个字符串 // 此处的 二级指针 可以使用 指针数组 / 二维数组 / 自定义二级指针内存 // 此处选择的模型是 自定义二级指针内存 char **team; }Student;
2、为 结构体内的二级指针成员 分配内存
为二级指针成员分配内存时 , 先为二级指针分配内存 , 再为一级指针分配内存 ;
核心业务逻辑 :
// 为每个结构体的 address 成员分配内存 for(i = 0; i < count; i++) { // 为一级指针分配内存模型 tmp[i].address = (char *)malloc(20); // 为 二级指针 内存模型分配内存 , 分配 3 个 一级指针 变量内存 char **p = (char **)malloc(3 * sizeof(char *)); // 为 二级指针 指向的 一级指针 分配内存 for(j = 0; j < 3; j++) { // 每个一级指针分配 10 字节数据 p[j] = (char *)malloc(10 * sizeof(char)); } // 将分配好内存的 二级指针 模型 , 赋值给结构体中的二级指针 tmp[i].team = p; }
代码示例 :
/** * @brief create_student 堆内存中分配内存 * 为二级指针成员分配内存时 , 先为二级指针分配内存 , 再为一级指针分配内存 * @param array 二级指针 , 指向结构体数组 * @return */ int create_student(Student **array, int count) { // 返回值 int ret = 0; // 循环控制变量 int i = 0, j = 0; // 临时变量 Student *tmp = NULL; // 验证二级指针合法性 if(array == NULL) { ret = -1; return ret; } // 堆内存中申请内存 tmp = (Student *)malloc(sizeof(Student) * count); // 初始化分配的内存 memset(tmp, 0, sizeof(Student) * count); // 为每个结构体的 address 成员分配内存 for(i = 0; i < count; i++) { // 为一级指针分配内存模型 tmp[i].address = (char *)malloc(20); // 为 二级指针 内存模型分配内存 , 分配 3 个 一级指针 变量内存 char **p = (char **)malloc(3 * sizeof(char *)); // 为 二级指针 指向的 一级指针 分配内存 for(j = 0; j < 3; j++) { // 每个一级指针分配 10 字节数据 p[j] = (char *)malloc(10 * sizeof(char)); } // 将分配好内存的 二级指针 模型 , 赋值给结构体中的二级指针 tmp[i].team = p; } // 通过间接赋值 设置返回值 *array = tmp; return ret; }
3、释放 结构体内的二级指针成员 内存
释放内存时 , 先释放 二级指针 指向的 一级指针 的内存 , 再释放 二级指针 内存 ;
核心业务逻辑 :
// 释放 每个结构体的 address 成员分配内存 for(i = 0; i < count; i++) { // 释放一级指针 free((*array)[i].address); (*array)[i].address = NULL; // 释放二级指针指向的一级指针 for(j = 0; j < 3; j++) { if((*array)[i].team[j] != NULL){ free( (*array)[i].team[j] ); (*array)[i].team[j] = NULL; } } // 释放二级指针 if((*array)[i].team != NULL) { free( (*array)[i].team ); (*array)[i].team = NULL; } }
代码示例 :
/** * @brief free_student 释放内存 * 释放内存时 , 先释放 二级指针 指向的 一级指针 的内存 , 再释放 二级指针 内存 * @param array * @return */ int free_student(Student **array, int count) { // 返回值 int ret = 0; // 循环控制变量 int i = 0, j = 0; // 验证二级指针合法性 if(array == NULL) { ret = -1; return ret; } // 释放 每个结构体的 address 成员分配内存 for(i = 0; i < count; i++) { // 释放一级指针 free((*array)[i].address); (*array)[i].address = NULL; // 释放二级指针指向的一级指针 for(j = 0; j < 3; j++) { if((*array)[i].team[j] != NULL){ free( (*array)[i].team[j] ); (*array)[i].team[j] = NULL; } } // 释放二级指针 if((*array)[i].team != NULL) { free( (*array)[i].team ); (*array)[i].team = NULL; } } // 释放 结构体内存 free(*array); // 指针置空 , 防止野指针 *array = NULL; return ret; }
二、完整代码示例
完整代码示例 :
#include <stdio.h> #include <stdlib.h> #include <string.h> /** * @brief The Student struct * 定义 结构体 数据类型 , 同时为该结构体类型声明 别名 * 可以直接使用 别名 结构体变量名 声明结构体类型变量 * 不需要在前面添加 struct 关键字 */ typedef struct Student { // 声明变量时 , 会自动分配这 5 字节内存 // 赋值时 , 可以直接使用 = 赋值字符串 char name[5]; int age; int id; // 声明变量时 , 只会为 4 字节指针分配内存 // 具体的 字符串内存 需要额外使用 malloc 申请内存 // 赋值时 , 必须使用 strcpy 函数 , 向堆内存赋值 char *address; // 学生小组成员 , 由多个字符串组成 // 二级指针 , 指向多个 一级指针 // 每个 一级指针 指向 一个字符串 // 此处的 二级指针 可以使用 指针数组 / 二维数组 / 自定义二级指针内存 // 此处选择的模型是 自定义二级指针内存 char **team; }Student; /** * @brief printf_struct_array 打印结构体数组 * @param array 数组作为函数参数退化为指针 * @param count 数组中的元素个数 */ void printf_struct_array(Student *array, int count) { // 循环控制变量 int i = 0; // 验证数组合法性 if(array == NULL) { return; } // 打印结构体数组中的 结构体 age 字段 for(i = 0; i < count; i++) { printf("Student age = %d\n", array[i].age); } } /** * @brief sort_struct_array 对结构体数组 按照年龄进行排序 * @param array 结构体指针 * @param count 结构体数组的元素个数 */ void sort_struct_array(Student *array, int count) { // 循环控制变量 int i = 0, j = 0; // 学生年龄 Student tmp; // 验证数组合法性 if(array == NULL) { return; } // 排序 for(i = 0; i < count; i++) { for(j = i + 1; j < count; j++) { if(array[i].age > array[j].age) { tmp = array[i]; array[i] = array[j]; array[j] = tmp; } } } } /** * @brief create_student 堆内存中分配内存 * 为二级指针成员分配内存时 , 先为二级指针分配内存 , 再为一级指针分配内存 * @param array 二级指针 , 指向结构体数组 * @return */ int create_student(Student **array, int count) { // 返回值 int ret = 0; // 循环控制变量 int i = 0, j = 0; // 临时变量 Student *tmp = NULL; // 验证二级指针合法性 if(array == NULL) { ret = -1; return ret; } // 堆内存中申请内存 tmp = (Student *)malloc(sizeof(Student) * count); // 初始化分配的内存 memset(tmp, 0, sizeof(Student) * count); // 为每个结构体的 address 成员分配内存 for(i = 0; i < count; i++) { // 为一级指针分配内存模型 tmp[i].address = (char *)malloc(20); // 为 二级指针 内存模型分配内存 , 分配 3 个 一级指针 变量内存 char **p = (char **)malloc(3 * sizeof(char *)); // 为 二级指针 指向的 一级指针 分配内存 for(j = 0; j < 3; j++) { // 每个一级指针分配 10 字节数据 p[j] = (char *)malloc(10 * sizeof(char)); } // 将分配好内存的 二级指针 模型 , 赋值给结构体中的二级指针 tmp[i].team = p; } // 通过间接赋值 设置返回值 *array = tmp; return ret; } /** * @brief free_student 释放内存 * 释放内存时 , 先释放 二级指针 指向的 一级指针 的内存 , 再释放 二级指针 内存 * @param array * @return */ int free_student(Student **array, int count) { // 返回值 int ret = 0; // 循环控制变量 int i = 0, j = 0; // 验证二级指针合法性 if(array == NULL) { ret = -1; return ret; } // 释放 每个结构体的 address 成员分配内存 for(i = 0; i < count; i++) { // 释放一级指针 free((*array)[i].address); (*array)[i].address = NULL; // 释放二级指针指向的一级指针 for(j = 0; j < 3; j++) { if((*array)[i].team[j] != NULL){ free( (*array)[i].team[j] ); (*array)[i].team[j] = NULL; } } // 释放二级指针 if((*array)[i].team != NULL) { free( (*array)[i].team ); (*array)[i].team = NULL; } } // 释放 结构体内存 free(*array); // 指针置空 , 防止野指针 *array = NULL; return ret; } /** * @brief 主函数入口 * @return */ int main(int argc, char* argv[], char**env) { // 声明结构体数组 , 该数组在栈内存中 Student *array = NULL; // 循环控制变量 int i = 0; // 堆内存中为结构体指针分配内存 create_student(&array, 2); // 命令行中 , 接收输入的年龄 for(i = 0; i < 2; i++) { // 命令换行中 接收 输入的年龄 , // 设置到 Student 数组元素的 age 成员中 printf("\n Input Age :\n"); scanf("%d", &(array[i].age)); printf("\n Input ID :\n"); scanf("%d", &(array[i].id)); printf("\n Input Name :\n"); scanf("%s", array[i].name); printf("\n Input Address :\n"); scanf("%s", array[i].address); printf("\n Input Team 1 Name :\n"); scanf("%s", array[i].team[0]); printf("\n Input Team 2 Name :\n"); scanf("%s", array[i].team[1]); printf("\n Input Team 3 Name :\n"); scanf("%s", array[i].team[2]); } // 结构体数组 按照 age 排序 sort_struct_array(array, 2); // 打印结构体数组中的 结构体 age 字段 printf_struct_array(array, 2); // 释放堆内存数据 free_student(&array, 2); // 命令行不要退出 system("pause"); return 0; }
执行结果 :
Input Age : 18 Input ID : 1 Input Name : Tom Input Address : CHina Input Team 1 Name : Tom1 Input Team 2 Name : Tom2 Input Team 3 Name : Tom3 Input Age : 16 Input ID : 2 Input Name : Jerry Input Address : Beijing Input Team 1 Name : Jerry1 Input Team 2 Name : Jerry2 Input Team 3 Name : Jerry3 Student age = 16 Student age = 18 请按任意键继续. . .