现在位置: 首页 > C 教程 > 正文

C 库函数 - free()

C 标准库 - <stdlib.h> C 标准库 - <stdlib.h>

描述

在 C 语言中,free() 函数是标准库函数,用于释放由 malloc(), calloc(), realloc() 等动态分配函数分配的内存。当动态分配的内存不再需要时,调用 free() 函数可以避免内存泄漏,确保程序有效地管理内存。

声明

下面是 free() 函数的声明。

void free(void *ptr)

参数

  • ptr -- 指针指向一个要释放内存的内存块,该内存块之前是通过调用 malloc、calloc 或 realloc 进行分配内存的。如果传递的参数是一个空指针,则不会执行任何动作。

返回值

该函数不返回任何值。

实例

下面的实例演示了 free() 函数的用法。

实例

#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *str; /* 最初的内存分配 */ str = (char *) malloc(15); strcpy(str, "runoob"); printf("String = %s, Address = %p\n", str, str); /* 重新分配内存 */ str = (char *) realloc(str, 25); strcat(str, ".com"); printf("String = %s, Address = %p\n", str, str); /* 释放已分配的内存 */ free(str); return(0); }

让我们编译并运行上面的程序,这将产生以下结果:

String = runoob,  Address = 0x7fe4e4c02b10
String = runoob.com,  Address = 0x7fe4e4c02b10

注意事项

  • 释放正确的内存:只能释放通过动态内存分配函数分配的内存,不能释放由其他方式分配的内存(例如局部变量或全局变量)。

  • 避免重复释放:同一个内存块不能多次释放,否则可能导致未定义行为。

  • 释放后指针处理:释放内存后,指针仍然指向已释放的内存位置。为了避免悬空指针,可以将指针设为 NULL

    free(array);
    array = NULL;
  • 检查空指针:调用 free() 前最好检查指针是否为空,以确保程序稳定性。

    if (array != NULL) {
        free(array);
        array = NULL;
    }

通过正确使用 free() 函数,可以确保动态分配的内存被合理管理,避免内存泄漏和悬空指针的问题,提高程序的稳定性和可靠性。


内存泄漏与悬空指针

  • 内存泄漏:如果动态分配的内存没有被释放或丢失了对其的引用,内存将无法再被程序使用,造成内存泄漏。
  • 悬空指针:指向已释放内存的指针称为悬空指针。如果悬空指针被再次访问,会导致未定义行为,可能引起程序崩溃或数据损坏。

在 C 语言中,调用 free() 释放动态分配的内存后,该指针仍然保存着之前分配的地址,这会导致悬空指针(dangling pointer)。悬空指针是指向已释放内存的指针,如果对其进行解引用操作,会导致未定义行为。

为了避免悬空指针问题,通常的做法是在调用 free() 之后,将指针设置为 NULL。这样可以确保程序不会误使用已释放的内存。

实例

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

int main() {
    // 动态分配内存
    char *str = (char *)malloc(100 * sizeof(char));
    if (str == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    // 使用分配的内存
    snprintf(str, 100, "Hello, World!");
    printf("%s\n", str);

    // 释放动态分配的内存
    free(str);
   
    // 将指针设置为 NULL,避免悬空指针
    str = NULL;

    // 现在 str 已经是 NULL,安全地避免了悬空指针问题
    if (str == NULL) {
        printf("str is NULL\n");
    }

    return 0;
}

在这个示例中,str 指针在 free() 调用之后被设置为 NULL,这样就避免了悬空指针问题。如果尝试再次使用这个指针,由于它是 NULL,可以通过条件检查避免未定义行为。

C 标准库 - <stdlib.h> C 标准库 - <stdlib.h>