Anastasia
Anastasia

Reputation: 184

Null pointer not detected

I am new to C++. I expected two pointers that don't point to anything to be detected as null pointers. However this works only with one of them. The physical addresses of those pointers are somewhat different - 0xe00000001 vs 0x0 (this one is properly detected as null pointer).

I've written the following snippet of code:

#include <iostream>
using namespace std;

struct TNode {
    TNode* Parent;  // Pointer to the parent node
    TNode* Left;  // Pointer to the left child node
    TNode* Right;  // Pointer to the right child node
    int Key;  // Some data
};

int main() {
    TNode parent;
    parent.Key = 2;
    TNode first;
    first.Key = 1;
    first.Parent = &parent;
    parent.Left = &first;
    cout << first.Left << endl; // get 0xe00000001 here
    cout << first.Right <<endl; // get 0x0

    if (first.Right == nullptr) {
        cout <<"rnull"<<endl; // rnull
    }
    if (first.Left == nullptr) {
        cout <<"lnull"<<endl; // nothing
    }

   return 0;
}

What is going on here? Basically, I want to find a way to check whether first.Left points to nothing.

Upvotes: 1

Views: 906

Answers (2)

Alecto
Alecto

Reputation: 10740

In your example, first.Left and first.Right are uninitialized, not null. This means that they basically contain whatever garbage was on the stack at the time they were allocated. Accessing the actual value (by printing the pointer, for example) is actually undefined behavior, but with most compilers on low optimization settings it'll just print that garbage.

Solution 1: give default values to member variables

If you want them to be null, you can modify TNode so that their initial value is guaranteed to be null:

struct TNode {
    TNode* Parent = nullptr;
    TNode* Left = nullptr;
    TNode* Right = nullptr; 
    int Key = 0;
};

int main() {
    TNode n; //Everything initialized to null or 0
}

This will guarantee that they're null.

Solution 2: Define TNode() to initialize members

Alternatively, you could also explicitly define the constructor so that it makes everything null

struct TNode {
    TNode* Parent, Left, Right;
    // Everything gets default-initialized to null
    TNode() : Parent(), Left(), Right() {}
};

int main() {
    Tnode n; // Everything initialized to nullptr or 0
}

Solution 3: default-initialize at the point of use

Even if you don't explicitly define a constructor, everything gets initialized to 0 (or null, if it's a pointer) when you explicitly initialize it by putting {} when declaring the variable.

struct TNode {
    TNode* Parent, Left, Right;
    int Key;
};

int main() {

    TNode iAmUninitialized; // This one is uninitialized

    Tnode iAmInitialized{}; //This one has all it's members initialized to 0
}

Upvotes: 5

jwh20
jwh20

Reputation: 678

First of all, in C and C++ there is no such thing as a pointer that points to nothing. Regardless of the value in the pointer, it points at something. Even NULL is a pointer to address "0" but we use that, by convention to represent a NULL. The problem with a pointer that is uninitialized is that it can point to anything and that anything is likely an illegal address which will cause an exception or it points to something else in the application and, if the data is modified, will cause an undesired side-effect.

In your case the 2nd pointer is 0x00 and that is NULL. The 1st pointer, however, is 0x01, and that is NOT NULL.

Upvotes: 0

Related Questions