【问题标题】:How to use nullptr properly?如何正确使用 nullptr?
【发布时间】:2017-12-16 12:00:30
【问题描述】:

目前我正在阅读 Byarne Stroustrup 的“C++ 之旅”。重要的是:关于“指针、数组和引用”,他举了一个关于使用nullptr 的例子:

int count_x(char* p, char x)
// count the number of occurrences of x in p[]
// p is assumed to point to a zero-terminated array of char (or to nothing)
{

    if (p == nullptr) return 0;
        int count = 0;

    for (; p != nullptr; ++p)
        if (*p == x)
            ++count;

    return count;
}

在我的主目录中:

int main(){

    char* str = "Good morning!";
    char c = 'o';
    std::cout << count_x(str, c) << std::endl;

    return 0;
}

当我运行程序崩溃时,我在行抛出异常

if (*p == x)

如果我把循环改成这样:

for (; *p; p++)
    if (*p == x)
        ++count;

现在一切正常!我正在使用 MSVC++ 14.0。

  • 我在ideone 上运行的相同代码我没有遇到异常,但结果始终是0,应该是3

https://ideone.com/X9BeVx

【问题讨论】:

  • @DeiDei:是的,我刚刚复制并粘贴了代码。我添加的是主要代码。
  • @DeiDei:这应该如何正确:*p != nullptr?我猜nullptr 仅适用于地址指针指向的地址,而不是它们指向的地址中的值。
  • 我在“C++ 之旅”的任何勘误表中都没有找到这个。你应该写信给 Bjarne 让他知道。这是一个错误。
  • 来自online version 的代码使用正确的检查 - 你从哪里复制代码?
  • 顺便说一句,char* str = "Good morning!"; 不是有效的 C++ 代码。 str 应该是 const char* 类型。 MSVC++ 太宽松了。

标签: c++ nullptr


【解决方案1】:

p != nullptr*p 执行非常不同的检查。

前者检查指针本身是否包含非空地址。而后者检查指向的地址是否包含不为 0 的内容。一个显然适合循环,其中检查缓冲区的内容,而另一个则不是。

您出现段错误是因为您从未停止读取缓冲区(有效指针在递增时不太可能产生 null)。因此,您最终访问的方式超出了缓冲区限制。

【讨论】:

  • 但这被认为是不正确的:*p = nullptr 不是吗?
  • @WonFeiHong - 是的,那是不正确的。 *p 没有指针类型,因此无法与 nullptr 进行比较。尝试时会出现编译器错误
  • 是的,如果你想让比较更明确,你可以做 *p != '\0' 虽然 *p 也可以正常工作......
【解决方案2】:

记住您使用的是 C 语言功能。

您的问题出在for 循环中。在指针到达 字符数组 的最后一个元素后,它指向数组的末尾而不是 nullptr

假设您有一个字符数组,例如 const char *a ="world"ptr 指向

     +-----+     +---+---+---+---+---+---+
ptr :| *======>  | w | o | r | l | d |\0 |
     +-----+     +---+---+---+---+---+---+  

ptr 指向的最后一个元素是'\0',在您的for 中,您应该如下更改您的代码:


for (; *p != 0; p++) {
        if (*p == x)
            ++count;
    }

输出:3

【讨论】:

  • @hnefatl- 你希望我做什么?
猜你喜欢
  • 1970-01-01
  • 2022-12-09
  • 1970-01-01
  • 2020-12-04
  • 2012-07-12
  • 2013-01-21
  • 2021-10-24
  • 2011-12-22
  • 2020-10-14
相关资源
最近更新 更多