C语言中的null定义

用C语言编程不能不说指针,说道指针又不能不提NULL,那么NULL究竟是个什么东西呢? C语言中又定义,定义如下:

复制代码

#undef NULL
#if defined(__cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif

复制代码

所以我觉得,如果一个指针被赋予NULL,应该就相当于这个指针执行了0x0000这个逻辑地址,但是C语言中0x0000这个逻辑地址用户是不能使用的(有些人说是因为0x0000没有映射到物理地址,也有人说是因为0x0000映射到的地址是操作系统用于判断野指针的,我也不太懂,总之就是用户不能使用啦),所以当你试图取一个指向了NULL的指针的内容时,就会提示段错误,听着有点绕,看程序:

int *node=NULL;
int a=0;
a=*node;

printf("%d\n",a);

 

由于node执行的是NULL,也就是逻辑地址0x0000,而这个地址用于是不能访问的,所以编译器提示段错误。

还在网上看到了一个面试题,和这个问题有关,分享一下:

按 Ctrl+C 复制代码

 

按 Ctrl+C 复制代码

运行结果依然是段错误。因为函数是值传递,node指针变量的值并没有被改变,所以这个程序的效果和上一个程序的效果是一样的。

 

如果要让结果为100,应该怎样写代码呢? 答案是 传递node指针变量的指针给fun,也就是传递一个二级指针,当然相应的fun函数也应该做出改变,代码如下:

复制代码

#include <stdio.h>

void fun(int ** node)
{
    static int N=100;
    *node=&N;
}

int main()
{
    int *node=NULL;
    int a=0;

    fun(&node);
    a=*node;

    printf("%d\n",a);
    return 0;

}

复制代码

 

### C语言中的NULL #### NULL定义 在C语言中,`NULL` 是一个宏定义,用来表示空指针常量。这个宏通常被定义为整数常量 `0` 或者 `(void *)0`,用于表示一个无效的地址[^1]。 ```c #define NULL ((void *)0) ``` 这段代码展示了 `NULL` 的典型定义方式,在标准库头文件 `<stddef.h>` 中可以找到该定义。 #### 初始化变量 当声明指针时,将其初始化为 `NULL` 是一种良好的编程习惯。这有助于防止未初始化指针带来的潜在错误,因为任何尝试访问指向 `NULL` 地址的数据都会立即引发明显的运行时异常或崩溃,从而更容易调试问题[^2]。 ```c int *ptr = NULL; ``` 上述代码片段展示了一个简单的例子,其中创建了一个名为 `ptr` 的整型指针并赋初值为空(`NULL`)。 #### 释放内存后的处理 动态分配内存之后,如果不再需要这块空间,则应该调用 `free()` 来回收资源,并立即将对应的指针设回 `NULL`。这样做能够有效预防悬挂指针(hanging pointer),即已经释放但仍持有旧位置引用的情况发生[^3]。 ```c char *buffer = (char*)malloc(100); // ... use buffer ... if(buffer != NULL){ free(buffer); buffer = NULL; // 防止悬挂指针 } ``` 这里给出了完整的流程:先申请一段字符数组作为缓冲区;接着执行某些操作;最后安全地清理掉这部分存储区域的同时确保不会留下危险状态下的悬空指针。 #### 动态内存管理配合NULL检查 考虑到 `malloc()` 返回的是可能失败的结果——特别是在系统资源紧张的情况下可能会返回 `NULL` ——所以在每次成功获取到新近开辟出来的堆区内存之前都应当做必要的有效性验证[^4]: ```c #include <stdio.h> #include <stdlib.h> int main(){ int *data = (int*)malloc(sizeof(int)); if(data == NULL){ // 检查是否分配成功 printf("Memory allocation failed\n"); return -1; } *data = 42; printf("%d\n",*data); free(data); data=NULL; return 0; } ``` 此示例说明了如何正确地请求一块大小合适的新内存块给定类型对象使用,并且包含了基本的安全措施以应对可能出现的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值