Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use nullptr properly?

Tags:

c++

nullptr

currently I am reading "A tour of C++" by Byarne Stroustrup. The thing that matters: on "pointers, arrays and references" he gave an example about using nullptr like this:

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;
}

In my my main:

int main(){

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

    return 0;
}

When I run the program it crashes I get an exception thrown at line

if (*p == x)

If I change the loop to be like this:

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

Now everything works fine! I am using MSVC++ 14.0.

  • The same code I ran on ideone I don't get an exception but the result is always 0 which should be 3:

https://ideone.com/X9BeVx

like image 678
WonFeiHong Avatar asked Dec 16 '17 12:12

WonFeiHong


People also ask

When should I use nullptr?

The nullptr keyword can be used to test if a pointer or handle reference is null before the reference is used. Function calls among languages that use null pointer values for error checking should be interpreted correctly. You cannot initialize a handle to zero; only nullptr can be used.

Is nullptr false?

If the scalar value is equal to 0, the Boolean value is 0; otherwise the Boolean value is 1. A zero, null pointer, or null member pointer value is converted to false . All other values are converted to true . A null pointer with the nullptr value is converted to false .

Should I use null or nullptr?

nullptr is a keyword that represents zero as an address (its type is considered a pointer-type), while NULL is the value zero as an int . If you're writing something where you're referring to the zero address, rather than the value zero, you should use nullptr .

Does nullptr return false?

- In the context of a direct-initialization, a bool object may be initialized from a prvalue of type std::nullptr_t, including nullptr. The resulting value is false.


2 Answers

p != nullptr and *p perform very different checks.

The former checks that the pointer itself contains a non-null address. While the latter checks that the address being pointed at contains something that is not 0. One is clearly appropriate in the loop, where the buffer's content is checked, while the other is not.

You segfault because you never stop reading the buffer (a valid pointer is unlikely to produce null when it is incremented). So you end up accessing way beyond your buffer limit.

like image 87
StoryTeller - Unslander Monica Avatar answered Nov 01 '22 13:11

StoryTeller - Unslander Monica


Remember that you are using C language feature.

Your problem is in your for loop. After the pointer reaches the last element of your character array it points to the end of the array not the nullptr.

Imagine you have a character array such as const char *a ="world" and ptr points to the

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

the last element which ptr points to is '\0' and in your for you should change your code as below:


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

output : 3

like image 1
Pouyan Avatar answered Nov 01 '22 12:11

Pouyan