【问题标题】:Why must I do null check in C++?为什么我必须在 C++ 中进行空值检查?
【发布时间】:2020-08-13 03:06:25
【问题描述】:

我想知道空值检查的必要性。

示例代码如下

#include <iostream>
bool twice( int* a )
{
    if( a == nullptr )
    {
        std::cout << "null" << std::endl;
        return true;
    }
    std::cout << *a << std::endl;
    *a *= 2;
    std::cout << *a << std::endl;
    return false;
}
int main()
{
    twice( nullptr );
    int v = 16;
    std::cout << v << std::endl;
    twice( &v );
    std::cout << v << std::endl;
}

这是输出

null
16
16
32
32

我知道'nullptr'是“指向内存地址零的指针”或“指针变量引用无效时的标志”。


第一季度。内存的零地址每个实内存只有一个?

第二季度。你能在这段代码中重现“指针变量的引用无效”吗?

第三季度。指针变量引用是什么函数失效了?

对不起,我的英语很差。

【问题讨论】:

  • 它没有指向内存中的特定部分。这就是为什么尝试使用空指针会崩溃的原因。
  • 如果您将函数twice() 更改为接受引用而不是指针,则无需进行空检查。调用者不可能将引用传递给不存在的对象(在您的情况下为int)。是的,调用者可以使用未定义的行为执行操作以创建然后传递无效引用(例如,通过取消引用空指针并传递它)。但是,如果调用者有未定义的行为,那么无论如何,所有的赌注都会被取消——你的函数不能可靠地检测到这种情况,或者安全地处理它。调用者有责任不这样做
  • 如果您可以保证(基于您对程序整体逻辑的理解)指针永远不会为空(或者如果您可以调用未定义的行为并可能崩溃,则不需要进行空检查当它为空时你的程序)。

标签: c++ pointers null-pointer


【解决方案1】:

我建议以不同的方式考虑这一点。而是将空指针视为“内存地址为零”,将其视为“此指针实际上并未指向任何东西”。

有了这种心智模型,您需要进行空值检查的原因就更清楚了。如果你有一个实际上并不指向任何东西的指针,那么写

*a  *=  2;

是一个无意义的操作 - a 没有指向任何东西,因此取消引用 a 以获取一个整数然后将该整数加倍不是一个明确定义的操作。

在内部,在大多数系统上,nullptr 被实现为“指向内存地址零的指针,这在大多数操作系统上被认为是无效的”,但我认为这并不能说明为什么这段代码需要空检查。

【讨论】:

  • 只是出于好奇:您写了 [...] 内存地址为零,这在大多数操作系统上被认为是无效的;它在哪个操作系统上有效?
  • @nada 我可以想象一些没有内存保护机制的嵌入式操作系统可能会将地址 0 映射到某个东西。我不知道有什么具体的操作系统可以做到这一点,但如果存在的话,我不会感到惊讶。
  • 感谢您的快速回答。我大概明白了。用这段代码不理解空指针会更好吗?这是因为用户必须输入“nullptr”才能使用此代码使输出为“null”,但没有人输入“nullptr”?我从未开发过系统。所以我很抱歉,但我不了解系统内部。如果您对 null 检查有一些简单的想法,我想知道。
  • @nada 过去,我曾经使用带有 MIPS CPU 和 SGI 操作系统 Irix 的 SGI 工作站。很长一段时间以来,我不知道这是可以访问 NULL 而没有通常预期的段错误或总线错误的平台之一。当我们将代码移植到使用 Linux 的 PC 时,我醒悟了——我们甚至没有达到main()。 ;-)
【解决方案2】:

指针只是指向内存地址的无符号整数。在某些具有虚拟内存的系统中,内存的第一页不会映射到物理内存。因此,当我们尝试在空指针地址处读取/写入时,会导致分段错误/页面错误。但是在某些嵌入式设备中,我们不会观察到分段错误问题,因为我们可以访问零内存空间

不考虑操作系统,为避免应用程序崩溃,添加空指针检查是个好习惯

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 2011-01-22
    • 2010-10-09
    • 2017-09-25
    • 2010-11-28
    • 2023-04-05
    • 2012-01-29
    相关资源
    最近更新 更多