C language implements malloc and free functions to complete memory management

1. Introduction to malloc and free functions

In C language, malloc and free are functions used for dynamic memory management.

(1) malloc function
The malloc function is used to allocate a memory space of a specified size in the heap and returns a pointer to the memory block.

The prototype is as follows:

void* malloc(size_t size);

The size parameter indicates the size of the memory block to be allocated, in bytes.

The function returns a pointer to the allocated memory block, or NULL if the allocation fails.

scenes to be used:

Dynamically allocate memory, such as creating data structures as needed while the program is running.

Dynamically allocate memory space for strings, arrays, structures, etc.

Instructions:

#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 function
The free function is used to release the memory space that was previously dynamically allocated through the malloc or calloc function.

The prototype is as follows:

void free(void* ptr);
The ptr parameter is a pointer to a previously allocated memory block. If ptr is NULL, the free function does nothing.

scenes to be used:

Releases dynamically allocated memory through functions such as malloc, calloc, or realloc.

Avoid memory leaks, i.e. freeing memory that is no longer in use so that other code can use that memory.

Instructions:

#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;
}

Once the free function is called, you should avoid continuing to use the released memory. The released memory will no longer belong to the valid memory area of ​​the program and may be reused by other parts. Continuing to use freed memory after it has been freed can lead to undefined behavior and potential bugs.

2. Implement your own malloc and free functions

Define an array unsigned char buff[1024*100]; and then use C language code to write my_malloc and my_free functions to manage the space of this buff array. The user calls the my_malloc and my_free functions to manage this space.

Implementation code:

#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;
}

illustrate:

  1. The buff array is the total space used to store allocated memory blocks.
  2. The MemoryBlock structure is used to record the starting position and size of each memory block.
  3. The my_malloc function is used to allocate a memory block of a specified size, find a free block in the memoryBlocks array or allocate a new block, and return its starting address.
  4. The my_free function is used to free a previously allocated memory block, find the block to be freed in the memoryBlocks array, and set its size to 0.

In the main function, allocate the memory block by calling my_malloc and free the memory block by calling my_free

Guess you like

Origin blog.csdn.net/weixin_40933653/article/details/133501267