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

一、malloc和free函数介绍

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

(1)malloc函数

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

原型如下:

cpp 复制代码
void* malloc(size_t size);
  • size参数表示要分配的内存块的大小,以字节为单位。
  • 函数返回一个指向分配内存块的指针,如果分配失败,则返回NULL

使用场景:

  • 动态分配内存,例如在程序运行时根据需要创建数据结构。
  • 为字符串、数组、结构体等动态分配内存空间。

使用方法:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
​
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;
}

(2)free函数

free函数用于释放之前通过malloccalloc函数动态分配的内存空间。

原型如下:

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

使用场景:

  • 释放通过malloccallocrealloc等函数动态分配的内存。
  • 避免内存泄漏,即释放不再使用的内存,以便其他代码可以使用该内存。

使用方法:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
​
int main() {
    int* ptr = (int*)malloc(5 * sizeof(int));
    if (ptr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
​
    // 使用动态分配的内存
​
    // 释放内存
    free(ptr);
​
    return 0;
}

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

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

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

实现代码:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
​
#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;
}

说明:

  • buff数组是用于存储分配的内存块的总空间。

  • MemoryBlock结构体用于记录每个内存块的起始位置和大小。

  • my_malloc函数用于分配指定大小的内存块,在memoryBlocks数组中找到一个空闲块或分配一个新块,并返回其起始地址。

  • my_free函数用于释放先前分配的内存块,在memoryBlocks数组中查找要释放的块,并将其大小设置为0。

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

相关推荐
zquwei22 分钟前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
dessler44 分钟前
Docker-run命令详细讲解
linux·运维·后端·docker
Q_19284999061 小时前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端
ZSYP-S2 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
Yuan_o_2 小时前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
程序员一诺3 小时前
【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】
后端·python
DT辰白3 小时前
如何解决基于 Redis 的网关鉴权导致的 RESTful API 拦截问题?
后端·微服务·架构
thatway19894 小时前
AI-SoC入门:15NPU介绍
后端
陶庵看雪4 小时前
Spring Boot注解总结大全【案例详解,一眼秒懂】
java·spring boot·后端