MST
星途 面试题库

面试题:C语言结构体嵌套动态内存分配错误检测优化

定义一个结构体,其中包含一个指向另一个结构体数组的指针,内层结构体又包含动态分配的字符数组。编写代码实现内存分配,并阐述在多层动态分配结构体内存过程中,可能出现的错误点以及如何优化错误检测机制,以避免内存泄漏和悬空指针等问题。
42.7万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

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

// 定义内层结构体
typedef struct Inner {
    char *str;
} Inner;

// 定义外层结构体
typedef struct Outer {
    Inner *innerArray;
} Outer;

// 分配内存函数
void allocateMemory(Outer *outer, int size) {
    outer->innerArray = (Inner *)malloc(size * sizeof(Inner));
    if (outer->innerArray == NULL) {
        fprintf(stderr, "内存分配失败\n");
        return;
    }
    for (int i = 0; i < size; i++) {
        outer->innerArray[i].str = (char *)malloc(100 * sizeof(char));
        if (outer->innerArray[i].str == NULL) {
            // 释放之前分配的内存
            for (int j = 0; j < i; j++) {
                free(outer->innerArray[j].str);
            }
            free(outer->innerArray);
            fprintf(stderr, "内存分配失败\n");
            return;
        }
        strcpy(outer->innerArray[i].str, "示例字符串");
    }
}

// 释放内存函数
void freeMemory(Outer *outer, int size) {
    for (int i = 0; i < size; i++) {
        free(outer->innerArray[i].str);
    }
    free(outer->innerArray);
}

int main() {
    Outer outer;
    int size = 5;
    allocateMemory(&outer, size);

    // 使用结构体数据

    freeMemory(&outer, size);
    return 0;
}

多层动态分配结构体内存过程中可能出现的错误点:

  1. 内存分配失败:在调用 malloc 时可能由于系统内存不足等原因导致分配失败,如 outer->innerArray = (Inner *)malloc(size * sizeof(Inner));outer->innerArray[i].str = (char *)malloc(100 * sizeof(char)); 这两步分配操作。如果不检查返回值,后续使用未成功分配的指针会导致程序崩溃。
  2. 内存泄漏:如果在分配内层结构体数组元素的字符数组时失败,而之前已经分配了内层结构体数组,没有及时释放内层结构体数组的内存,就会造成内存泄漏。例如上述代码中如果 outer->innerArray[i].str 分配失败,而没有释放之前 outer->innerArray 已分配的内存。
  3. 悬空指针:当释放了内存,但没有将指针设置为 NULL 时,指针仍然指向已释放的内存区域,成为悬空指针。后续如果误使用该指针,可能导致未定义行为。

优化错误检测机制避免内存泄漏和悬空指针等问题的方法:

  1. 检查内存分配结果:每次调用 malloc 后,立即检查返回值是否为 NULL,如上述代码中所做的,若为 NULL 则及时处理,比如释放之前已分配的内存并给出错误提示。
  2. 按顺序释放内存:释放内存时,按照分配的相反顺序进行。先释放内层结构体中的动态分配内存(如字符数组),再释放外层结构体中指向内层结构体数组的指针。
  3. 置空指针:在释放内存后,将指针设置为 NULL。例如在 freeMemory 函数中,释放完 outer->innerArray 后,可添加 outer->innerArray = NULL;,这样可以避免悬空指针问题。