【C++】在C++中空指针用NULL来初始化还合适吗?

C++中NULL初始化空指针是否合适探讨

目录

问题引入

1. C++98中的空指针

1.1 指针的危险性

2. C++11中的空指针


问题引入

在C++11的新特性中,我们使用nullptr来表示指针空值。那为什么放着好好的NULL不用未使用nullptr呢?那肯定是发明C++的大佬们发现了什么NULL使用过程的bug,让我们一起来探讨一下。

1. C++98中的空指针

我们知道,良好的编程习惯要求我们,在定义指针时就要进行赋初值(初始化),否则将会产生难以预料的错误。

1.1 指针的危险性

C++在创建指针时,会分配用来储存这个指针本身(也就是用来储存地址)的内存空空间,但是并不会分配指针所指向的内存空间。而为数据提供空间是一个独立的步骤,如果忽略这一步无疑是自找麻烦:

int* fellow;
*fellow = 1234;

我们画图来理解(图中的内存地址是编造的):

int* fellow;

这一句的作用就是,定义了一个指针follow,并将地址为0x0001的空间分配给了follow。然后我们并没有进行指针的初始化,所以此时0x0001这块内存中将会储存一个随机的地址(我们也不知道会是什么),而上面背景中的意思就是,这个随机储存的地址的空间并不会随之分配。

这里我们假设那个随机的地址是0x0080,然后执行下面:

*fellow = 1234;

也就是说我们给一个没有初始化的指针(一个随机地址0x0080)上赋值了1234,如果0x0080正好使我们follow需要的地址(但是这个概率相当于大海捞针)还能接受,但是这个地址一旦是某一个程序已经使用的内存空间将会发生不可估计的错误,可能是数据损坏,甚至系统崩溃

因此为了避免这个问题,我们都要给指针进行初始化。通常情况下我们是这样进行初始化的:

int main()
{
	//空指针定义
	int* p1 = NULL;
	int* p2 = 0;
 
	return 0;
}

实际上,NULL是一个宏定义,我们在C语言的传统文件中就可以看到如下代码:

可以看到NULL,可能被定义为字面常量0,或者是无类型指针(void*)的常量。但是使用这种空值的指针会出现一下新的问题,来分析一下这段代码:

void f(int)
{
	cout << "f(int)" << endl;
}
void f(int*)
{
	cout << "f(int*)" << endl;
}
 
int main()
{
	f(0);
	f(NULL);
 
	return 0;
}

我们定义两个函数(对这里的函数重载有疑问的可以看),按照正常的想法,应该是f(0)进入f(int),f(NULL)进入f(int*),所以我们预期的打印结果是:

f(int)
f(int*)

但是运行结果:

很明先与我们想的有出入,但是这是为什么呢?

其实应该比较容易想清楚,我们本来想使用空指针NULL这样能够进入f(int*),但是在预处理阶段NULL就已经被宏定义替换成了0,所以也就进入了函数f(int),这也就是为什么打印出两个相同的结果。

在C++98中,NULL既可以是一个整型数字0,也可以是一个没有类型的指针(void*)常量,但是编译器默认会先将其当做一个整型数字0,如果想要编译器将其当做指针来处理,就必须要进行void*。


2. C++11中的空指针

发明C++的大佬们在C++11中,为了避免这个问题,使用关键字nullptr来表示空指针。

int main()
{
	f(0);
	f(NULL);
	f(nullptr);
 
	return 0;
}

我们加上nullptr来看一下运行结果:

此时我们会发现nullptr就解决了这个问题。

注意:

  • 使用nullptr时,并不需要包含头文件,因为C++11中,nullptr是作为关键字引入的
  • 在C++11中sizeof(nullptr)和sizeof(void*)

  • 为了代码的健壮性,还是希望小伙伴们习惯在初始化空指针的时候使用nullptr 

(本篇完) 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值