C 库函数 - free()
描述
在 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;
}
#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,可以通过条件检查避免未定义行为。