MST
星途 面试题库

面试题:C语言动态内存分配中的内存泄漏场景及解决方法

在C语言中,简述至少两种可能导致动态内存分配后发生内存泄漏的场景,并说明如何避免这些内存泄漏问题。例如在使用malloc分配内存后,在哪些情况下可能会忘记释放内存,以及怎样的代码结构能确保内存正确释放。
19.3万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

场景一:函数返回前未释放内存

  • 场景描述:在一个函数内部使用malloc分配了内存,但是函数在返回前没有调用free释放该内存。如果多次调用这个函数,就会不断产生内存泄漏。
  • 示例代码
char* createString() {
    char* str = (char*)malloc(100 * sizeof(char));
    // 对str进行操作
    return str;
    // 这里没有释放str指向的内存,会导致内存泄漏
}
  • 避免方法:在函数返回前添加free操作。
char* createString() {
    char* str = (char*)malloc(100 * sizeof(char));
    // 对str进行操作
    char* result = str;
    free(str);
    return result;
}

场景二:异常情况下未释放内存

  • 场景描述:在分配内存后,代码执行过程中发生异常(例如条件判断失败、函数调用出错等),导致程序流程跳过了释放内存的代码。
  • 示例代码
void processData() {
    int* arr = (int*)malloc(10 * sizeof(int));
    if (arr == NULL) {
        return;
    }
    // 假设这里有一个可能失败的操作
    if (someFunctionThatMayFail()) {
        // 直接返回,没有释放arr指向的内存
        return;
    }
    // 正常处理数据
    free(arr);
}
  • 避免方法:在异常发生处添加释放内存的代码,或者使用goto语句统一管理内存释放。
void processData() {
    int* arr = (int*)malloc(10 * sizeof(int));
    if (arr == NULL) {
        return;
    }
    // 假设这里有一个可能失败的操作
    if (someFunctionThatMayFail()) {
        free(arr);
        return;
    }
    // 正常处理数据
    free(arr);
}

使用goto的方式:

void processData() {
    int* arr = (int*)malloc(10 * sizeof(int));
    if (arr == NULL) {
        return;
    }
    // 假设这里有一个可能失败的操作
    if (someFunctionThatMayFail()) {
        goto cleanup;
    }
    // 正常处理数据
cleanup:
    free(arr);
}

场景三:指针丢失

  • 场景描述:当重新分配内存或改变指针指向时,忘记释放原来指针指向的内存。
  • 示例代码
void modifyString() {
    char* str = (char*)malloc(10 * sizeof(char));
    strcpy(str, "hello");
    char* newStr = (char*)malloc(20 * sizeof(char));
    strcpy(newStr, str);
    str = newStr;
    // 此时原来str指向的内存没有释放,发生内存泄漏
    free(str);
}
  • 避免方法:在改变指针指向之前,先释放原来指针指向的内存。
void modifyString() {
    char* str = (char*)malloc(10 * sizeof(char));
    strcpy(str, "hello");
    char* newStr = (char*)malloc(20 * sizeof(char));
    strcpy(newStr, str);
    free(str);
    str = newStr;
    free(str);
}