MST
星途 面试题库

面试题:C语言malloc函数底层实现模拟

请尝试用C语言模拟实现一个简易版本的malloc函数,包括内存分配和释放功能。假设底层有一个简单的内存池(可以使用数组模拟),你需要考虑内存的管理、分配算法(如首次适配)、释放后内存块的合并等问题。同时说明在实现过程中如何处理多线程环境下的内存分配与释放,以确保线程安全。
48.7万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define MEMORY_POOL_SIZE 1024

// 定义内存块结构体
typedef struct MemoryBlock {
    size_t size;
    int is_free;
    struct MemoryBlock *next;
} MemoryBlock;

// 内存池
static char memory_pool[MEMORY_POOL_SIZE];
// 内存块链表头
static MemoryBlock *head = NULL;
// 互斥锁
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

// 初始化内存池
void init_memory_pool() {
    head = (MemoryBlock *)memory_pool;
    head->size = MEMORY_POOL_SIZE - sizeof(MemoryBlock);
    head->is_free = 1;
    head->next = NULL;
}

// 首次适配算法分配内存
void* my_malloc(size_t size) {
    pthread_mutex_lock(&mutex);
    MemoryBlock *current = head;
    MemoryBlock *prev = NULL;

    while (current != NULL) {
        if (current->is_free && current->size >= size) {
            if (current->size >= size + sizeof(MemoryBlock)) {
                // 分割内存块
                MemoryBlock *new_block = (MemoryBlock *)((char *)current + sizeof(MemoryBlock) + size);
                new_block->size = current->size - size - sizeof(MemoryBlock);
                new_block->is_free = 1;
                new_block->next = current->next;

                current->size = size;
                current->is_free = 0;
                current->next = new_block;
            } else {
                current->is_free = 0;
            }
            pthread_mutex_unlock(&mutex);
            return (void *)((char *)current + sizeof(MemoryBlock));
        }
        prev = current;
        current = current->next;
    }
    pthread_mutex_unlock(&mutex);
    return NULL;
}

// 释放内存并合并相邻的空闲块
void my_free(void* ptr) {
    pthread_mutex_lock(&mutex);
    if (ptr == NULL) {
        pthread_mutex_unlock(&mutex);
        return;
    }
    MemoryBlock *current = (MemoryBlock *)((char *)ptr - sizeof(MemoryBlock));
    current->is_free = 1;

    // 合并前一个空闲块
    if (current != head && ((MemoryBlock *)((char *)current - sizeof(MemoryBlock)))->is_free) {
        MemoryBlock *prev = (MemoryBlock *)((char *)current - sizeof(MemoryBlock));
        prev->size += current->size + sizeof(MemoryBlock);
        prev->next = current->next;
        current = prev;
    }

    // 合并后一个空闲块
    if (current->next != NULL && current->next->is_free) {
        current->size += current->next->size + sizeof(MemoryBlock);
        current->next = current->next->next;
    }
    pthread_mutex_unlock(&mutex);
}

// 多线程环境下的处理说明:
// 在my_malloc和my_free函数中,通过pthread_mutex_lock和pthread_mutex_unlock对共享资源(内存块链表)进行加锁和解锁操作,
// 以确保在多线程环境下,对内存的分配和释放操作是线程安全的。只有获取到互斥锁的线程才能对内存块链表进行操作,
// 避免了多个线程同时修改链表导致的数据不一致问题。

// 示例测试函数
void* thread_func(void* arg) {
    int *data = (int *)my_malloc(sizeof(int));
    if (data != NULL) {
        *data = 42;
        printf("Thread allocated memory at %p, value: %d\n", data, *data);
        my_free(data);
    }
    return NULL;
}

int main() {
    init_memory_pool();

    pthread_t threads[5];
    for (int i = 0; i < 5; i++) {
        pthread_create(&threads[i], NULL, thread_func, NULL);
    }

    for (int i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }

    pthread_mutex_destroy(&mutex);
    return 0;
}