MST

星途 面试题库

面试题:C语言自定义内存分配器与内存泄漏检测及调试的深度结合

假设你要设计一个自定义的C语言内存分配器,如何在这个分配器的设计中融入内存泄漏检测机制,并且在发生内存泄漏时,能够方便地定位到具体的代码位置,阐述详细的设计思路和关键实现步骤。
27.2万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 记录内存分配信息:在每次分配内存时,记录分配的内存地址、大小以及分配该内存的代码位置(如文件名、行号)。这可以通过自定义的数据结构来实现。
  2. 跟踪内存释放:每次释放内存时,从记录的分配信息中移除相应的记录。
  3. 检测内存泄漏:在程序结束或特定的检测点,检查记录的分配信息中是否存在未被释放的内存。如果存在,则表明发生了内存泄漏。
  4. 定位泄漏位置:对于检测到的内存泄漏,利用之前记录的代码位置信息,方便开发人员定位到具体的代码行。

关键实现步骤

  1. 定义数据结构
typedef struct {
    void *address;
    size_t size;
    const char *file;
    int line;
    struct MemoryRecord *next;
} MemoryRecord;

MemoryRecord *head = NULL;
  1. 修改内存分配函数
void* my_malloc(size_t size, const char *file, int line) {
    void *ptr = malloc(size);
    if (ptr) {
        MemoryRecord *newRecord = (MemoryRecord*)malloc(sizeof(MemoryRecord));
        newRecord->address = ptr;
        newRecord->size = size;
        newRecord->file = file;
        newRecord->line = line;
        newRecord->next = head;
        head = newRecord;
    }
    return ptr;
}
  1. 修改内存释放函数
void my_free(void *ptr) {
    MemoryRecord *current = head;
    MemoryRecord *prev = NULL;
    while (current) {
        if (current->address == ptr) {
            if (prev) {
                prev->next = current->next;
            } else {
                head = current->next;
            }
            free(current);
            free(ptr);
            return;
        }
        prev = current;
        current = current->next;
    }
}
  1. 添加内存泄漏检测函数
void detect_memory_leaks() {
    MemoryRecord *current = head;
    while (current) {
        printf("Memory leak detected at %s:%d, address: %p, size: %zu\n", 
               current->file, current->line, current->address, current->size);
        current = current->next;
    }
}
  1. 使用宏方便调用
#define my_malloc(size) my_malloc(size, __FILE__, __LINE__)

在程序结束前调用detect_memory_leaks函数,即可检测并定位内存泄漏。