MST
星途 面试题库

面试题:C语言realloc函数在复杂场景下的应用

在一个动态数组管理的系统中,数组元素类型为自定义结构体struct Node { int data; struct Node *next; }; 系统需要根据用户输入动态增加或减少数组元素个数。请设计一个函数,使用realloc来完成该动态数组的内存调整工作,同时要考虑内存碎片化问题以及如何优化内存使用效率。详细说明你的设计思路以及在不同情况下(如增加元素、减少元素)函数的具体实现步骤。
30.5万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 内存碎片化问题
    • 尽量减少内存分配和释放的次数。当增加元素时,如果当前数组的剩余空间足够,就直接在原数组上添加元素,避免频繁调用realloc导致内存碎片化。
    • 当减少元素时,不急于释放内存,而是将释放的空间标记为可用,下次增加元素时优先使用这些标记的空间,从而减少内存碎片。
  2. 优化内存使用效率
    • 采用合理的内存增长策略。例如,每次增加元素时,如果原数组已满,按照一定的增长率(如翻倍)来分配新的内存,而不是只增加一个元素的空间,这样可以减少realloc的调用次数。
    • 减少不必要的内存拷贝。在realloc时,如果新分配的内存地址与原地址相同,就不需要进行数据拷贝,直接使用原数据。

函数实现

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

// 自定义结构体
struct Node {
    int data;
    struct Node *next;
};

// 动态数组管理函数
struct Node* adjustArray(struct Node* arr, int* size, int capacity, int newSize, int growthRate) {
    if (newSize < 0) {
        printf("Invalid new size.\n");
        return arr;
    }

    if (newSize <= capacity) {
        // 减少元素时不释放内存,只更新size
        if (newSize < *size) {
            *size = newSize;
        }
        return arr;
    }

    // 增加元素且原空间不足
    int newCapacity = capacity;
    while (newSize > newCapacity) {
        newCapacity *= growthRate;
    }

    struct Node* newArr = (struct Node*)realloc(arr, newCapacity * sizeof(struct Node));
    if (!newArr) {
        printf("Memory allocation failed.\n");
        return arr;
    }

    // 更新size和capacity
    *size = newSize;
    return newArr;
}

不同情况下的具体实现步骤

  1. 增加元素
    • 首先检查新的元素个数newSize是否超过当前数组的容量capacity
    • 如果未超过,直接在原数组的size位置添加新元素,并更新size
    • 如果超过,按照设定的增长率(如growthRate为2)计算新的容量newCapacity,直到newCapacity大于等于newSize
    • 调用realloc分配新的内存空间,并将原数组的数据拷贝到新数组(如果realloc返回的地址与原地址不同)。
    • 更新数组指针arr、数组大小size和数组容量capacity
  2. 减少元素
    • 检查新的元素个数newSize是否小于当前数组的大小size
    • 如果是,只更新size,不释放内存,标记释放的空间为可用,供下次增加元素时使用。
    • 如果newSize大于等于size,则不做任何处理,返回原数组。

示例使用

int main() {
    struct Node* arr = NULL;
    int size = 0;
    int capacity = 0;
    int growthRate = 2;

    // 增加元素
    arr = adjustArray(arr, &size, capacity, 5, growthRate);
    capacity = 5;

    // 减少元素
    arr = adjustArray(arr, &size, capacity, 3, growthRate);

    free(arr);
    return 0;
}

这样设计可以在一定程度上解决内存碎片化问题并优化内存使用效率。