[C++] std::string 为啥允许空指针char*字符串作为参数来构造对象
周五的时候团队进行代码审查,金某某同学分享了一个因为空指针来产生的崩溃。代码类似下面这样:
bool check_referrer(const char* ref) { std::string strRef(ref); // ... }
,这是一个提供给别人调用的函数。在别人传了一个 NULL 作为参数调用此函数时,std::string() 在构造时内存访问异常了。
于是有人就开问了,std::string() 允许使用 NULL 作为参数来构造吗?既然崩溃了,那说明不能,那为什么 std::string() 在构造的时候没有进行检测呢?
然而,我并不这样认为。我的观点是:NULL(0) 在某些情况下也是合法的字符串指针。
如果你玩过一些硬件,比如单片机,红白机等,就应该明白,开发人员有足够的权限去操作 NULL 指向的内存,NULL 就是指向以 0 为开始地址的内存区。
但在 x86 系统的具有保护模式的 CPU 架构上,操作系统为了捕捉到 空指针 对象,所以限制了 应用层 的代码不能访问以 0 开始的这一块内存区。并且,这一块内存区的大小在 x86 上是 64KB,所以就算 std::string() 要判断参数是否有效,光 != NULL 是完全不行的,应该是 0 <= p <= 64kb,对吧?但是这样有意义吗?
什么叫标准库?标准库就不能特定于某平台。在 Windows 上 NULL 是无效的字符串指针,但你不能说 NULL 在其它平台也是无效的。很明显,C++ 不是只用于 Windows,为 C++ 开发的标准库当然也不是只用于 Windows,就算这套标准库是 Windows 开发的。
标准库没有错,错在犯错的你太理所当然了。