在C语言开发中,指针是操作内存的核心工具,但错误的指针操作往往会引发程序崩溃、内存泄漏等严重问题,因此对指针是否为NULL的检查是编写健壮代码的基础环节。NULL在C语言中是一个表示空指针的宏,通常定义为((void *)0),用来标识指针不指向任何有效的内存地址。

基础检查方式
最直接、最常用的检查指针是否为NULL的方式是使用相等或不相等运算符进行判断,这也是C语言标准推荐的做法。以下是一段简单的示例代码,展示如何检查一个整型指针是否为NULL:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr = NULL; // 初始化指针为NULL
// 检查指针是否为NULL
if (ptr == NULL) {
printf("指针ptr是NULL,未指向有效内存n");
} else {
printf("指针ptr不是NULL,指向有效内存n");
}
// 也可以反过来判断,检查指针非空
if (ptr != NULL) {
// 只有当指针非空时才操作指针指向的内容,避免非法内存访问
*ptr = 10;
}
return 0;
}
检查逻辑的注意事项
在检查指针是否为NULL时,有几个常见的错误需要避免:
- 不要将NULL放在等号左侧进行判断,虽然
if (NULL == ptr)和if (ptr == NULL)逻辑上等价,但前者容易因为笔误写成if (NULL = ptr)导致编译错误,而后者写成if (ptr = NULL)只会把ptr赋值为NULL,不会报错,反而隐藏问题。 - 不要直接判断指针是否等于0,虽然NULL通常定义为0,但使用NULL可读性更强,也更符合C语言的规范,避免和其他整型变量的判断混淆。
- 指针释放内存后,应该及时将其赋值为NULL,避免成为野指针,后续检查的时候才能正确识别。
动态内存分配场景下的检查
在使用malloc、calloc、realloc等函数动态分配内存时,这些函数在分配失败时会返回NULL,因此必须对返回的指针进行检查,否则后续对指针的操作会导致程序崩溃。以下是动态内存分配时的指针检查示例:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = (int *)malloc(10 * sizeof(int));
// 必须检查malloc返回的指针是否为NULL
if (arr == NULL) {
printf("内存分配失败,指针为NULLn");
return 1; // 分配失败直接退出程序
}
// 内存分配成功,正常使用指针
for (int i = 0; i < 10; i++) {
arr[i] = i;
}
// 使用完内存后释放
free(arr);
arr = NULL; // 释放后将指针置为NULL,避免野指针
// 后续如果再次使用arr,先检查是否为NULL
if (arr != NULL) {
// 这里的代码不会执行,因为arr已经被置为NULL
arr[0] = 10;
}
return 0;
}
函数参数中的指针检查
当函数的参数是指针类型时,为了防止调用方传入NULL指针导致函数内部出错,通常需要在函数开头对指针参数进行检查。以下是一个字符串处理函数的示例,展示参数指针的检查逻辑:
#include <stdio.h>
#include <string.h>
// 自定义的字符串长度计算函数,带指针检查
int my_strlen(const char *str) {
// 检查传入的指针是否为NULL
if (str == NULL) {
printf("传入的字符串指针为NULLn");
return -1; // 返回错误标识
}
int len = 0;
while (str[len] != ' ') {
len++;
}
return len;
}
int main() {
char *s1 = "hello";
char *s2 = NULL;
printf("s1的长度:%dn", my_strlen(s1));
printf("s2的长度:%dn", my_strlen(s2));
return 0;
}
常见误区说明
很多开发者会误以为检查指针是否为NULL就能完全避免指针相关的错误,实际上NULL检查只能判断指针是否指向空地址,无法判断指针是否指向已经释放的内存或者越界的内存。对于已经释放的指针,只有手动将其赋值为NULL,后续的NULL检查才能生效,否则指针仍然是野指针,检查无法通过。因此除了做好NULL检查,还要注意指针的生命周期管理,避免不必要的指针悬空问题。