• C语言实现malloc与free函数完成内存管理


    一、malloc和free函数介绍

    在C语言中,malloc和free是用于动态内存管理的函数。

    (1)malloc函数
    malloc函数用于在堆(heap)中分配指定大小的内存空间,并返回一个指向该内存块的指针。

    原型如下:

    void* malloc(size_t size);
    
    • 1

    size参数表示要分配的内存块的大小,以字节为单位。

    函数返回一个指向分配内存块的指针,如果分配失败,则返回NULL。

    使用场景:

    动态分配内存,例如在程序运行时根据需要创建数据结构。

    为字符串、数组、结构体等动态分配内存空间。

    使用方法:

    #include 
    #include 
    
    int main() {
        int* ptr;
        int num = 5;
    
        // 动态分配内存
        ptr = (int*)malloc(num * sizeof(int));
        if (ptr == NULL) {
            printf("内存分配失败\n");
            return 1;
        }
    
        // 使用指针访问和操作分配的内存
        for (int i = 0; i < num; i++) {
            ptr[i] = i + 1;
        }
    
        // 打印分配的内存
        for (int i = 0; i < num; i++) {
            printf("%d ", ptr[i]);
        }
    
        // 释放内存
        free(ptr);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    (2)free函数
    free函数用于释放之前通过malloc或calloc函数动态分配的内存空间。

    原型如下:

    void free(void* ptr);
    ptr参数是一个指向先前分配的内存块的指针。如果ptr为NULL,则free函数不执行任何操作。

    使用场景:

    释放通过malloc、calloc或realloc等函数动态分配的内存。

    避免内存泄漏,即释放不再使用的内存,以便其他代码可以使用该内存。

    使用方法:

    #include 
    #include 
    
    int main() {
        int* ptr = (int*)malloc(5 * sizeof(int));
        if (ptr == NULL) {
            printf("内存分配失败\n");
            return 1;
        }
    
        // 使用动态分配的内存
    
        // 释放内存
        free(ptr);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    一旦调用了free函数,就应该避免继续使用已释放的内存,已释放的内存将不再属于程序的有效内存区域,并且可能被其他部分重用。在释放内存后继续使用已释放的内存会导致未定义的行为和潜在的错误。

    二、实现自己的malloc和free函数

    定义一个数组 unsigned char buff[1024*100]; 然后使用C语言代码写个my_malloc和my_free函数,对这个buff数组的空间进行管理。 用户调用my_malloc和my_free函数管理这段空间。

    实现代码:

    #include 
    #include 
    
    #define BUFF_SIZE (1024 * 100)
    
    unsigned char buff[BUFF_SIZE];
    
    typedef struct {
        unsigned char* start;
        size_t size;
    } MemoryBlock;
    
    MemoryBlock memoryBlocks[BUFF_SIZE] = {0};
    int numBlocks = 0;
    
    void* my_malloc(size_t size) {
        // 寻找空闲块
        for (int i = 0; i < numBlocks; i++) {
            if (memoryBlocks[i].size == 0 && size <= BUFF_SIZE) {
                memoryBlocks[i].start = buff;
                memoryBlocks[i].size = size;
                return memoryBlocks[i].start;
            }
        }
    
        // 分配新的块
        if (numBlocks < BUFF_SIZE) {
            memoryBlocks[numBlocks].start = buff + numBlocks;
            memoryBlocks[numBlocks].size = size;
            numBlocks++;
            return memoryBlocks[numBlocks - 1].start;
        }
    
        // 分配失败
        return NULL;
    }
    
    void my_free(void* ptr) {
        // 查找要释放的块
        for (int i = 0; i < numBlocks; i++) {
            if (memoryBlocks[i].start == ptr) {
                memoryBlocks[i].size = 0;
                break;
            }
        }
    }
    
    int main() {
        // 使用my_malloc和my_free进行内存管理
        unsigned char* ptr1 = (unsigned char*)my_malloc(10);
        unsigned char* ptr2 = (unsigned char*)my_malloc(20);
    
        if (ptr1 != NULL && ptr2 != NULL) {
            // 使用分配的内存
            for (int i = 0; i < 10; i++) {
                ptr1[i] = i;
            }
    
            for (int i = 0; i < 20; i++) {
                ptr2[i] = i + 10;
            }
    
            // 打印分配的内存
            printf("ptr1: ");
            for (int i = 0; i < 10; i++) {
                printf("%d ", ptr1[i]);
            }
            printf("\n");
    
            printf("ptr2: ");
            for (int i = 0; i < 20; i++) {
                printf("%d ", ptr2[i]);
            }
            printf("\n");
        }
    
        my_free(ptr1);
        my_free(ptr2);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    说明:

    1. buff数组是用于存储分配的内存块的总空间。
    2. MemoryBlock结构体用于记录每个内存块的起始位置和大小。
    3. my_malloc函数用于分配指定大小的内存块,在memoryBlocks数组中找到一个空闲块或分配一个新块,并返回其起始地址。
    4. my_free函数用于释放先前分配的内存块,在memoryBlocks数组中查找要释放的块,并将其大小设置为0。

    在main函数中,通过调用my_malloc来分配内存块,并通过调用my_free来释放内存块

  • 相关阅读:
    进制A+B [牛客网]
    判断两个二叉树是否相等
    超越 ChatGPT-4,谷歌结合 AlphaGo 技术的多模态大模型 Gemini 已小范围内测
    JAVA:实现将位置 i 处的字符与位置 j 处的字符交换的函数算法(附完整源码)
    创新研报 | 如何激发中国半导体企业发展潜力从而获得竞争优势,领跑新一轮增长?
    点云地面滤波--布料模拟滤波(CSF)
    机器学习 —— 简单模型的构建
    【吴恩达机器学习-笔记整理】诊断偏差较大(欠拟合)、方差较大(过拟合)的情况及其解决方案
    jtag调试ls1012a linux-5.3内核
    JavaScript学习(七)——事件练习
  • 原文地址:https://blog.csdn.net/weixin_40933653/article/details/133501267