动态内存管理:C语言malloc极简封装方案(修正版,可申请二维数组)

动态内存管理:C语言极简封装方案(修正版)

🛠️ 核心封装(1次写,终身用,无错误)

1. 安全开辟内存(底层核心)

c 复制代码
void* malloc_safe(size_t size) {
    void* ptr = malloc(size);
    if (ptr == NULL) { // 自动判断内存分配失败
        fprintf(stderr, "内存分配失败!\n");
        exit(1);
    }
    return ptr;
}

2. 通用释放内存(统一释放+置空)

c 复制代码
void free_safe(void** ptr, int is_2d, int rows) {
    if (*ptr == NULL) return; // 避免重复释放

    // 二维数组需逐行释放
    if (is_2d && rows > 0) {
        void** row_ptr = (void**)*ptr;
        for (int i = 0; i < rows; i++) {
            free(row_ptr[i]);
            row_ptr[i] = NULL;
        }
    }

    free(*ptr);
    *ptr = NULL;
}

🎯 极简调用宏(关键!一行搞定)

宏1:开辟1D数组/单个元素

c 复制代码
#define MALLOC(type, n) (type*)malloc_safe(sizeof(type) * (n))
  • 用法MALLOC(类型, 元素个数)

  • 示例

    c 复制代码
    int* arr1D = MALLOC(int, 10);
    char* str = MALLOC(char, 50);

宏2:开辟2D数组(修正版)

c 复制代码
#define MALLOC_2D(ptr, type, row, col) \
    ptr = (type**)malloc_safe(sizeof(type*) * (row)); \
    for (int i = 0; i < (row); i++) { \
        ptr[i] = MALLOC(type, col); \
    }
  • 用法MALLOC_2D(指针名, 类型, 行数, 列数)

  • 示例

    c 复制代码
    double** arr2D;
    MALLOC_2D(arr2D, double, 5, 3); // 5行3列

📝 测试示例(已验证可直接编译运行)

c 复制代码
#include <stdio.h>
#include <stdlib.h>

// 在此插入上述核心封装代码

int main() {
    // 1. 测试1D数组
    int* arr1D = MALLOC(int, 10);
    arr1D[0] = 100;
    printf("1D数组第1个元素:%d\n", arr1D[0]);

    // 2. 测试2D数组
    double** arr2D;
    MALLOC_2D(arr2D, double, 5, 3);
    arr2D[0][0] = 3.14;
    printf("2D数组[0][0]元素:%.2f\n", arr2D[0][0]);

    // 3. 测试自定义结构体
    typedef struct { int id; char name[20]; } Student;
    Student* stu1D = MALLOC(Student, 4);
    stu1D[0].id = 1;
    printf("结构体1D数组第1个id:%d\n", stu1D[0].id);

    Student** stu2D;
    MALLOC_2D(stu2D, Student, 3, 2);
    stu2D[0][0].id = 2;
    printf("结构体2D数组[0][0]id:%d\n", stu2D[0][0].id);

    // 4. 统一释放
    free_safe((void**)&arr1D, 0, 0);    // 释放1D数组
    free_safe((void**)&arr2D, 1, 5);    // 释放2D数组(传行数5)
    free_safe((void**)&stu1D, 0, 0);    // 释放结构体1D数组
    free_safe((void**)&stu2D, 1, 3);    // 释放结构体2D数组(传行数3)

    return 0;
}

⚠️ 核心错误说明

之前版本有两个致命错误:

  1. 宏定义错误

    • MALLOC_2D宏内使用了ptr但未将赋值结果传给外部指针
    • 宏内多写了分号,导致循环被隔断,语法错误
  2. 释放逻辑缺失

    • free_safe没有逐行释放二维数组的内存
    • 直接释放外层指针会导致内存泄漏(每行的内存永远无法释放)

修正后的核心优势

优势 说明
极简调用 1D数组:MALLOC(类型, 个数);2D数组:MALLOC_2D(指针名, 类型, 行, 列)
完全通用 适配int/double/结构体等所有类型,1D/2D数组通杀
安全无错 自动判空(避免崩溃)、逐行释放(避免泄漏)、置空指针(杜绝野指针)
即拿即用 测试示例直接对应实际用法,复制就能用,无需额外修改

📋 关键用法总结

✅ 开辟内存(一行搞定)

场景 用法 示例
一维数组/单个元素 MALLOC(类型, 元素个数) char* str = MALLOC(char, 50);
二维数组 MALLOC_2D(指针名, 类型, 行数, 列数) int** matrix; MALLOC_2D(matrix, int, 4, 6);

✅ 释放内存(统一用法)

数组类型 释放语法 参数说明
一维数组 free_safe((void**)&指针名, 0, 0) 第2个参数传0(不是二维)
二维数组 free_safe((void**)&指针名, 1, 行数) 第2个参数传1,第3个传实际行数

🔄 编译运行

bash 复制代码
gcc -o memory_demo memory_demo.c
./memory_demo

输出结果:

复制代码
1D数组第1个元素:100
2D数组[0][0]元素:3.14
结构体1D数组第1个id:1
结构体2D数组[0][0]id:2

这套封装方案经过修正后,彻底解决了之前的错误,保持了"一行开辟、一行释放"的极简特性,同时确保了内存安全。所有代码均已验证,可直接复制使用。

相关推荐
梁正雄1 小时前
9、Python面向对象编程-1
服务器·开发语言·python
say_fall1 小时前
C++ 入门第一课:命名空间、IO 流、缺省参数与函数重载全解析
c语言·开发语言·c++
霸王大陆1 小时前
《零基础学 PHP:从入门到实战》模块十一:成为 PHP 侦探,精通错误处理与调试实战大全-1
开发语言·笔记·php·课程设计
赖small强1 小时前
【Linux C/C++开发】C++多态特性深度解析:从原理到实践
linux·c语言·c++·多态·虚函数表
郝学胜-神的一滴1 小时前
Python的内置类型:深入理解与使用指南
开发语言·python·程序人生
松☆1 小时前
C语言--结构体
c语言·开发语言
关于不上作者榜就原神启动那件事1 小时前
【java后端开发问题合集】
java·开发语言
LitchiCheng2 小时前
Mujoco 蒙特卡洛采样统计机械臂可达工作空间(非Matlab)
开发语言·matlab
真正的醒悟2 小时前
图解网络8
开发语言·网络·php