MST
星途 面试题库

面试题:C语言优化结构体池内存管理

假设你有一个频繁创建和销毁结构体实例的应用场景,使用malloc和free管理结构体池内存。请设计一种优化方案,以减少内存碎片并提高内存分配和释放的效率,描述具体思路和关键代码实现。
35.4万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

思路

  1. 内存池设计:预先分配一块较大的内存作为结构体池,避免频繁调用 mallocfree
  2. 空闲链表管理:使用一个空闲链表来记录结构体池中空闲的结构体位置,当需要创建新的结构体实例时,从空闲链表中获取空闲位置;当销毁结构体实例时,将其位置加入空闲链表。
  3. 对齐处理:确保结构体的内存分配满足对齐要求,以提高内存访问效率。

关键代码实现

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

// 定义结构体
typedef struct {
    // 结构体成员
    int data;
    // 下一个空闲结构体的指针
    struct MyStruct* next;
} MyStruct;

// 结构体池和空闲链表头
MyStruct* pool = NULL;
MyStruct* freeList = NULL;

// 初始化结构体池
void initPool(size_t numStructs) {
    // 分配结构体池内存
    pool = (MyStruct*)malloc(numStructs * sizeof(MyStruct));
    if (pool == NULL) {
        perror("malloc");
        return;
    }

    // 初始化空闲链表
    freeList = pool;
    for (size_t i = 0; i < numStructs - 1; ++i) {
        pool[i].next = &pool[i + 1];
    }
    pool[numStructs - 1].next = NULL;
}

// 从结构体池获取一个结构体实例
MyStruct* createInstance() {
    if (freeList == NULL) {
        // 空闲链表为空,可考虑扩展结构体池
        return NULL;
    }
    MyStruct* newInstance = freeList;
    freeList = freeList->next;
    return newInstance;
}

// 销毁结构体实例,将其归还到结构体池
void destroyInstance(MyStruct* instance) {
    instance->next = freeList;
    freeList = instance;
}

// 释放结构体池内存
void freePool() {
    free(pool);
    pool = NULL;
    freeList = NULL;
}

在上述代码中:

  1. initPool 函数用于初始化结构体池,并构建空闲链表。
  2. createInstance 函数从空闲链表中获取一个空闲的结构体实例。
  3. destroyInstance 函数将销毁的结构体实例归还到空闲链表。
  4. freePool 函数释放整个结构体池的内存。

通过这种方式,可以有效减少内存碎片,提高内存分配和释放的效率。