Test for a null pointer value in C++ - c++

It's not clear for me how can i do that in C++. In Objective-C I can check a object in this way
if (myValue != [NSNull null]) { … }
myValue is compared with a null object (returned by class method), so this works great , if object has a value, even nil, if statement will return true.
So question is how to test correctly for a null pointer value, i did this way
if (myValue != NULL)
{
qDebug() << "It is not null";
}
but it is not working.

In C++ there's really no concept of null value, only null pointers. You can't compare something that isn't a pointer to NULL.

A pointer in C++ essentially contains an address to some memory location where you object or data is stored. In this case, a "NULL Pointer" is just an empty memory address. This is represented as a zero value. So to check it, you would write something like this:
SomeClass *someClassPointer = // ... call some method to get pointer
// Check for null pointer
if (someClassPointer == 0)
{
// Pointer is null
}
This can be simplified by doing this:
if (someClassPointer)
{
// For checking that the pointer is not null
}
if (!someClassPointer)
{
// For checking that a pointer is null
}

Short answer: it depends.
Longer answer: First of all you can not compare a reference (if the type of myValue is something like T&) nor stack allocated objects (if myValue is just T) for null - these types are always allocated and not null (unless you screw up your stack or do other bad stuff - but you won't check for these cases, because than you will have bigger problems).
The only types you can check for null are pointers (myValue is something of type T*). For those types:
if you use C++98, you can check against 0. NULL is usually just a macro (#define NULL 0).
if you use the new C++11 there is a new nullptr keyword and you should check against this one.
Since 0 evaluates to false and anything else to true, you can also just use the pointer like a normal bool. A nullptr is of type nullptr_t and has operator bool() implemented - so you also can this one like you would use a bool.
In general: in C++98 the lack of nullptr is a source of errors, so if you can use C++11, ALWAYS use nullptr - never use NULL or 0 (int is just the wrong type to assign to a pointer or to compare with a pointer - if you have overladed methods you will run into problems since the compiler would use a method with an int parameter instead of a pointer type if it is suitable).
Let's assume you have two functions:
void foo(int a);
void foo(void *);
If you now call
foo(NULL);
the first function will get called (what probably is not what you want. So in C++11 you would write:
foo(nullptr);
while in C++98 you would have to write:
foo((void *)0);
This is one reason why the lack of null is/was a big issue before C++98. If you want to have something similar than in Objective-C, you could write the following function (for C++98):
template<typename T>
inline bool isNull(const T *obj) {
return obj == ((const T *) 0);
}
// to use it:
if (isNull(myType)) { //myType is a pointer to something
// some code
}
Although I never saw that one used in practice.
I hope this answer helps in understanding the concept in C++.

If i'm right, you want to check for null pointers. This is actually very easy in C++
Foo *pInstanc = new Foo;
if(pInstance)
{
//do something with pInstance
}

Related

c++ what does a dynamic cast of a unique pointer return?

I am trying to use lambdas to find a way to find how many specific derived classes are in a vector of Base class type.
std::vector<std::unique_ptr<Account>> openedAccounts;
int countCurrent = std::count_if(openedAccounts.begin(), openedAccounts.end(),
[](std::unique_ptr<Account> ptr) { return dynamic_cast<Current&>(*ptr) != nullptr; }); // I will call this for savings as well
The account is a base abstract class and the current is a derived class.
I am getting the error no operator != matches these operands".
HOwever, I thought dynamic cast can return a null ptr.
A dynamic cast returns exactly what you asked for.
You asked for Current& or a Current reference.
You probably want to ask this
return dynamic_cast<Current*>(ptr.get()) != nullptr;
I thought dynamic cast can return a null ptr.
Only when you dynamic cast into a pointer type.
References don't have a representation for null. When you dynamic cast into a reference type, then an exception will be thrown in cases where a pointer cast would have returned null.
what is the way to go about this then?
dynamic_cast<Current*>(ptr.get())
would work. However, designs that require dynamic_cast are often probably bad. dynamic_cast exists for mostly working around badly designed APIs.
I recommend considering alternative designs.
std::vector<std::unique_ptr<Account>> openedAccounts;
int countCurrent = std::count_if(openedAccounts.begin(), openedAccounts.end(),
[](std::unique_ptr<Account> ptr) { return dynamic_cast<Current&>(*ptr) != nullptr; }); // I will call this for savings as well
I see in this code 3 problems:
dynamic_cast<Current&> ... != nullptr - dynamic_cast throws an exception for references and never returns null_ptr.
Lambda is incorrect, since argument std::unique_ptr<Account> is an attempt to create a copy of something what should be unique.
if you have container of pointers to some abstraction and you have to do dynamic_cast then this is clear indication that abstraction used is invalid.
So this should look looks more like this:
class Account {
public:
virtual bool isCurrent() { return false; }
....
};
std::vector<std::unique_ptr<Account>> openedAccounts;
int countCurrent = std::count_if(openedAccounts.begin(), openedAccounts.end(),
[](const std::unique_ptr<Account>& ptr) { return ptr->isCurrent(); });
I undesutnd that last point is hard to process so here is the hacky fix:
int countCurrent = std::count_if(openedAccounts.begin(), openedAccounts.end(),
[](const std::unique_ptr<Account>& ptr) { return dynamic_cast<Current *>(ptr.get()) != nullptr; });

Nullptr and checking if a pointer points to a valid object

In a couple of my older code projects when I had never heard of smart pointers, whenever I needed to check whether the pointer still pointed to a valid object, I would always do something like this...
object * meh = new object;
if(meh)
meh->member;
Or when I needed to delete the object safely, something like this
if(meh)
{
delete meh;
meh = 0;
}
Well, now I have learned about the problems that can arise from using objects and pointers in boolean expressions both with literal numbers, the hard way :. And now I've also learned of the not so new but pretty cool feature of C++, the nullptr keyword. But now I'm curious.
I've already gone through and revised most of my code so that, for example, when deleting objects I now write
if(meh)
{
delete meh;
meh = nullptr;
}
Now I'm wondering about the boolean. When you pass just say an int into an if statement like this,
int meh;
if(meh)
Then it implicitly checks for zero without you needing to write it.
if(meh == 0) // does the exact same check
Now, will C++ do the same for pointers? If pass in a char * like this to an if statement?
char * meh;
if(meh)
Then will it implicitly compare it with nullptr? Because of how long I have been writing these ifs like this, it is second nature at this point to check if the pointers valid before using by typing if (object *) and then calling its members. If this is not the functionality why not? Too difficult to implement? Would solve some problems by removing yet another tiny way you could mess up your code.
In C, anything that's not 0 is true. So, you certainly can use:
if (ptrToObject)
ptrToObject->doSomething();
to safely dereference pointers.
C++11 changes the game a bit, nullptr_t is a type of which nullptr is an instance; the representation of nullptr_t is implementation specific. So a compiler may define nullptr_t however it wants. It need only make sure it can enforce proper restriction on the casting of a nullptr_t to different types--of which boolean is allowed--and make sure it can distinguish between a nullptr_t and 0.
So nullptr will be properly and implicitly cast to the boolean false so long as the compiler follows the C++11 language specification. And the above snippet still works.
If you delete a referenced object, nothing changes.
delete ptrToObject;
assert(ptrToObject);
ptrToObject = nullptr;
assert(!ptrToObject);
Because of how long I have been writing these ifs like this, it is second nature at this point to check if the pointers valid before using by typing if (object *) and then calling it's members.
No. Please maintain a proper graph of objects (preferably using unique/smart pointers). As pointed out, there's no way to determine if a pointer that is not nullptr points to a valid object or not. The onus is on you to maintain the lifecycle anyway.. this is why the pointer wrappers exist in the first place.
In fact, because the life-cycle of shared and weak pointers are well defined, they have syntactic sugar that lets you use them the way you want to use bare pointers, where valid pointers have a value and all others are nullptr:
Shared
#include <iostream>
#include <memory>
void report(std::shared_ptr<int> ptr)
{
if (ptr) {
std::cout << "*ptr=" << *ptr << "\n";
} else {
std::cout << "ptr is not a valid pointer.\n";
}
}
int main()
{
std::shared_ptr<int> ptr;
report(ptr);
ptr = std::make_shared<int>(7);
report(ptr);
}
Weak
#include <iostream>
#include <memory>
void observe(std::weak_ptr<int> weak)
{
if (auto observe = weak.lock()) {
std::cout << "\tobserve() able to lock weak_ptr<>, value=" << *observe << "\n";
} else {
std::cout << "\tobserve() unable to lock weak_ptr<>\n";
}
}
int main()
{
std::weak_ptr<int> weak;
std::cout << "weak_ptr<> not yet initialized\n";
observe(weak);
{
auto shared = std::make_shared<int>(42);
weak = shared;
std::cout << "weak_ptr<> initialized with shared_ptr.\n";
observe(weak);
}
std::cout << "shared_ptr<> has been destructed due to scope exit.\n";
observe(weak);
}
Now, will C++ do the same for pointers? If pass in a char * like this to an if statement?
So to answer the question: with bare pointers, no. With wrapped pointers, yes.
Wrap your pointers, folks.
It's not possible to test whether a pointer points to a valid object or not. If the pointer is not null but does not point to a valid object, then using the pointer causes undefined behaviour. To avoid this sort of error, the onus is on you to be careful with the lifetime of objects being pointed to; and the smart pointer classes help with this task.
If meh is a raw pointer then there is no difference whatsoever between if (meh) and if (meh != 0) and if (meh != nullptr). They all proceed iff the pointer is not null.
There is an implicit conversion from the literal 0 to nullptr .
It is always set a pointer to zero after invalidating it so that you know a pointer that's non-zero is valid" is an anti-pattern. What happens if you have two pointers to the same object? Setting one to zero won't be better and it does not affect the other.

Function argument as reference to avoid checking for NULL

If I have a function that takes in a pointer which should never be NULL, I usually do something like this:
void Foo(const somePointer* ptr)
{
if (ptr == NULL)
{
// Throw assertion
return;
}
// Do something
}
So now I check every time whether the pointer is NULL and if it is not set to NULL in the first place and not allocated either then that check is useless. So now I am thinking whether I should define my functions like so (although I realize that does not guarantee I get a valid object, at least it won't be NULL):
void Foo(const somePointer& ptr)
{
// No need to check anymore, client is responsible
// Do something
}
And before I do (or don't, depending on the answers I get here), I thought I would ask here and see what everyone has to say, especially its pros and cons.
Well, if you never ever want a non-existent object passed in, use a reference (Note: non-existent, not non-valid).
If you want that possibility, use a pointer.
A lot depends on the shape of your code - if you write a lot of stuff like this:
A * a = new A();
f( a );
then it seems sensible for f() to take a pointer, rather than to have to write:
f( *a );
Personally, I almost never check for NULLs, new can't return one, and if you find you have one you are probably already in UB land.
I think it's pointless as a safety check. It's marginally worthwhile as documentation, though.
If you make the change, all that will happen is that some user will change this code:
somePointer *ptr = something();
Foo(ptr);
To this:
somePointer *ptr = something();
Foo(*ptr);
Now, if ptr was null, then the first code is invalid, and it was their fault for passing null into a function whose parameter "should never be NULL". The second code is also invalid, and it was their fault for dereferencing a null pointer.
It's useful as documentation, in that maybe when they type the * character they will think, "oh, hang on, this better not be null". Whereas if all you've done is document that null is an invalid input (like, say, strlen does), then they'd have to read the documentation in order to know not to pass in a null pointer. In theory, the user of your code will check the docs instead of just mashing the keyboard with his face until he has something that compiles, and assuming that will work. In practice, we all have our less intelligent moments.

Is it possible to set an object to null?

Further in my code, I check to see check if an object is null/empty.
Is there a way to set an object to null?
An object of a class cannot be set to NULL; however, you can set a pointer (which contains a memory address of an object) to NULL.
Example of what you can't do which you are asking:
Cat c;
c = NULL;//Compiling error
Example of what you can do:
Cat c;
//Set p to hold the memory address of the object c
Cat *p = &c;
//Set p to hold NULL
p = NULL;
While it is true that an object cannot be "empty/null" in C++, in C++17, we got std::optional to express that intent.
Example use:
std::optional<int> v1; // "empty" int
std::optional<int> v2(3); // Not empty, "contains a 3"
You can then check if the optional contains a value with
v1.has_value(); // false
or
if(v2) {
// You get here if v2 is not empty
}
A plain int (or any type), however, can never be "null" or "empty" in any useful sense. Think of std::optional as a container in this regard.
If you don't have a C++17 compliant compiler at hand, you can use boost.optional instead. Some pre-C++17 compilers also offer std::experimental::optional, which should behave at least close to the actual std::optional. Check your compiler's manual for details.
You can set any pointer to NULL, though NULL is simply defined as 0 in C++:
myObject *foo = NULL;
Also note that NULL is defined if you include standard headers, but is not built into the language itself. If NULL is undefined, you can use 0 instead, or include this:
#ifndef NULL
#define NULL 0
#endif
As an aside, if you really want to set an object, not a pointer, to NULL, you can read about the Null Object Pattern.
You want to check if an object is NULL/empty. Being NULL and empty are not the same. Like Justin and Brian have already mentioned, in C++ NULL is an assignment you'd typically associate with pointers. You can overload operator= perhaps, but think it through real well if you actually want to do this. Couple of other things:
In C++ NULL pointer is very different to pointer pointing to an 'empty' object.
Why not have a bool IsEmpty() method that returns true if an object's variables are reset to some default state? Guess that might bypass the NULL usage.
Having something like A* p = new A; ... p = NULL; is bad (no delete p) unless you can ensure your code will be garbage collected. If anything, this'd lead to memory leaks and with several such leaks there's good chance you'd have slow code.
You may want to do this class Null {}; Null _NULL; and then overload operator= and operator!= of other classes depending on your situation.
Perhaps you should post us some details about the context to help you better with option 4.
Arpan
"an object" of what type?
You can certainly assign NULL (and nullptr) to objects of pointer types, and it is implementation defined if you can assign NULL to objects of arithmetic types.
If you mean objects of some class type, the answer is NO (excepting classes that have operator= accepting pointer or arithmetic types)
"empty" is more plausible, as many types have both copy assignment and default construction (often implicitly). To see if an existing object is like a default constructed one, you will also need an appropriate bool operator==

Checking for a null object in C++

I've mostly only worked with C and am running into some unfamiliar issues in C++.
Let's say that I have some function like this in C, which would be very typical:
int some_c_function(const char* var)
{
if (var == NULL) {
/* Exit early so we don't dereference a null pointer */
}
/* The rest of the code */
}
And let's say that I'm trying to write a similar function in C++:
int some_cpp_function(const some_object& str)
{
if (str == NULL) // This doesn't compile, probably because some_object doesn't overload the == operator
if (&str == NULL) // This compiles, but it doesn't work, and does this even mean anything?
}
Basically, all I'm trying to do is to prevent the program from crashing when some_cpp_function() is called with NULL.
What is the most typical/common way of doing this with an object C++ (that doesn't involve overloading the == operator)?
Is this even the right approach? That is, should I not write functions that take an object as an argument, but rather, write member functions? (but even if so, please answer the original question)
Between a function that takes a reference to an object, or a function that takes a C-style pointer to an object, are there reasons to choose one over the other?
Basically, all I'm trying to do is to
prevent the program from crashing when
some_cpp_function() is called with
NULL.
It is not possible to call the function with NULL. One of the purpose of having the reference, it will point to some object always as you have to initialize it when defining it. Do not think reference as a fancy pointer, think of it as an alias name for the object itself. Then this type of confusion will not arise.
A reference can not be NULL. The interface makes you pass a real object into the function.
So there is no need to test for NULL. This is one of the reasons that references were introduced into C++.
Note you can still write a function that takes a pointer. In this situation you still need to test for NULL. If the value is NULL then you return early just like in C. Note: You should not be using exceptions when a pointer is NULL. If a parameter should never be NULL then you create an interface that uses a reference.
A C++ reference is not a pointer nor a Java/C# style reference and cannot be NULL. They behave as if they were an alias to another existing object.
In some cases, if there are bugs in your code, you might get a reference into an already dead or non-existent object, but the best thing you can do is hope that the program dies soon enough to be able to debug what happened and why your program got corrupted.
That is, I have seen code checking for 'null references' doing something like: if ( &reference == 0 ), but the standard is clear that there cannot be null references in a well-formed program. If a reference is bound to a null object the program is ill-formed and should be corrected. If you need optional values, use pointers (or some higher level construct like boost::optional), not references.
As everyone said, references can't be null. That is because, a reference refers to an object. In your code:
// this compiles, but doesn't work, and does this even mean anything?
if (&str == NULL)
you are taking the address of the object str. By definition, str exists, so it has an address. So, it cannot be NULL. So, syntactically, the above is correct, but logically, the if condition is always going to be false.
About your questions: it depends upon what you want to do. Do you want the function to be able to modify the argument? If yes, pass a reference. If not, don't (or pass reference to const). See this C++ FAQ for some good details.
In general, in C++, passing by reference is preferred by most people over passing a pointer. One of the reasons is exactly what you discovered: a reference can't be NULL, thus avoiding you the headache of checking for it in the function.
You can use a special designated object as the null object in case of references as follows:
class SomeClass {
public:
int operator==(SomeClass &object) {
return (this == &object);
}
static SomeClass NullObject;
};
SomeClass SomeClass::NullObject;
void print(SomeClass &val) {
if(val == SomeClass::NullObject)
printf("\nNULL");
else
printf("\nNOT NULL");
}
You should use NULL only with pointers. Your function accepts a reference and they can't be NULL.
Write your function just like you would write it in C.
C++ references naturally can't be null, you don't need the check. The function can only be called by passing a reference to an existing object.
What is the most typical/common way of doing this with an object C++ (that doesn't involve overloading the == operator)?
Is this even the right approach? ie. should I not write functions that take an object as an argument, but rather, write member functions? (But even if so, please answer the original question.)
No, references cannot be null (unless Undefined Behavior has already happened, in which case all bets are already off). Whether you should write a method or non-method depends on other factors.
Between a function that takes a reference to an object, or a function that takes a C-style pointer to an object, are there reasons to choose one over the other?
If you need to represent "no object", then pass a pointer to the function, and let that pointer be NULL:
int silly_sum(int const* pa=0, int const* pb=0, int const* pc=0) {
/* Take up to three ints and return the sum of any supplied values.
Pass null pointers for "not supplied".
This is NOT an example of good code.
*/
if (!pa && (pb || pc)) return silly_sum(pb, pc);
if (!pb && pc) return silly_sum(pa, pc);
if (pc) return silly_sum(pa, pb) + *pc;
if (pa && pb) return *pa + *pb;
if (pa) return *pa;
if (pb) return *pb;
return 0;
}
int main() {
int a = 1, b = 2, c = 3;
cout << silly_sum(&a, &b, &c) << '\n';
cout << silly_sum(&a, &b) << '\n';
cout << silly_sum(&a) << '\n';
cout << silly_sum(0, &b, &c) << '\n';
cout << silly_sum(&a, 0, &c) << '\n';
cout << silly_sum(0, 0, &c) << '\n';
return 0;
}
If "no object" never needs to be represented, then references work fine. In fact, operator overloads are much simpler because they take overloads.
You can use something like boost::optional.