Function argument as reference to avoid checking for NULL - c++

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.

Related

Avoiding null pointer crashes in C++ by overloading operators - bad practice?

I'm starting to write a rather large Qt application and instead of using raw pointers I want to use smart pointers, as well as Qt's own guarded pointer called QPointer.
With both standard library smart pointers and Qt's pointers the application crashes when a NULL pointer is dereferenced.
My idea was that I could add a custom overload to the dereference operators * and -> of these pointer types that check if the pointer is NULL.
Below is a short example that works fine so far. If a NULL pointer was dereferenced, a temporary dummy object would be created so that the application does not crash. How this dummy object would be processed might not be always correct, but at least there would be no crash and I could even react on this and show a warning or write it to a log file.
template <class T>
class Ptr : public std::shared_ptr<T> {
private:
T * m_temp;
public:
Ptr<T>(T * ptr) : std::shared_ptr<T>(ptr), m_temp(NULL) {}
~Ptr() {
if (m_temp) {
delete m_temp;
}
}
T * operator->() {
if (!std::shared_ptr<T>::get()) {
if (m_temp) {
delete m_temp;
}
m_temp = new T();
return m_temp;
} else {
return std::shared_ptr<T>::get();
}
}
T & operator*() {
return *operator->();
}
};
Of course I'll be doing NULL checks and try to eliminate the source of NULL pointers as much as possible, but for the rare case that it I forget a NULL check and the exception occurs, could this be a good way of handling it? Or is this a bad idea?
I would say this is a bad idea for a few reasons:
You cannot derive from standard library types. It may work until you change something benign in your code and then it breaks. There are various things you can do to make this more acceptable, but the easiest thing is to just not do this.
There are more ways to create a shared_ptr than just a constructor call. Duplicating the pointer value in your m_temp variable is likely just to lead things to be out of sync and cause more problems. By the time you cover all the bases, you will have probably re-implemented the whole shared_ptr class.
m_temp = new T(); seems like a frankly crazy thing to do if the old pointer is null. What about all the state stored in the object that was previously null? What about constructor parameters? Any initialization for the pointer? Sure, you could maybe handle all of these, but by that point you might as well handle the nullptr check elsewhere where things will be clearer.
You don't want to hide values being nullptr. If you have code using a pointer, it should care about the value of that pointer. If it is null and that is unexpected, then something further up the chain likely went wrong and you should be handling that appropriately (exceptions, error codes, logging, etc.). Silently allocating a new pointer will just hide the original source of the error. Whenever there is something wrong in a program, you want to stop or address the problem as close to the source as possible - it makes debugging the problem simpler.
A side note, if you are confident that your pointers are not null and don't want to have to deal with nullptr in a block of code, you may be able to use references instead. For example:
void fun1(MyObject* obj) {}
void fun2(MyObject& obj) {}
In fun1, the code might need to check for nullptr to be well written. In fun2, there is no need to check for nullptr because if someone converts a nullptr to a reference they have already broken the rules. fun2 pushes any responsibility for checking the pointer value higher up the stack. This can be good in some cases (just don't try and store the reference for later). Note that you can use operator * on a shared_ptr/unique_ptr to get a reference directly.

C++ - creating safe const char* contructor

I'm creating a class that has a constructor intialized from const char* which should safely construct an object using data provided in the buffer which should contain a string. My worries are, that the user can use this constructor with wrong data, e.g. NULL pointer or pointer to not-allocated memory or something like that. The point is, in that case I want to finish creating object (which will be in undefined, but correct state), without causing segfault if, for example, user sent me a pointer to data I shouldn't read. I thought of sending all input validation to std::string constructor, so the constructor would look like this:
Foo(const char *s) : Foo(std::string(s)) {}
But my teacher called this a "wrong idea". So, what is the proper way to deal with this situation then?
One more thing, I can't use exceptions in that case (this is part of my homework assignment in course which hasn't taught it yet).
The problem is that there are some things you absolutely cannot check for. The biggest of the group is a pointer to invalid memory. For example :
char* blarg = new char[50];
delete blarg;
Foo(blarg);
Here is another conversation about what you're asking. Some good answers are there but they basically say the same thing. When dealing with a pointer input there is no way to be 100% sure the user didn't do something stupid like calling delete on the pointer before passing it in.
My worries are, that the user can use this constructor with wrong data, e.g. NULL pointer or pointer to not-allocated memory or something like that. The point is, in that case I want to finish creating object (which will be in undefined, but correct state)
It's impossible to detect if a pointer is valid. It's has to be the responsibility of the caller to guarantee that it points to allocated memory.
However, you can detect if a pointer is null. You can check that and if it is, then set the state of the object without dereferencing the pointer.
I thought of sending all input validation to std::string constructor
But my teacher called this a "wrong idea".
Your teacher is correct. That won't help because std::string also requires and assumes that the input is valid. Constructing it with an invalid pointer leads to undefined behaviour.
So, what is the proper way to deal with this situation then?
Simply requiring the caller to guarantee the validity of the pointer is the right thing to - and all you can - do. If you want to check for null, feel free to do it.
If you have an error in your constructor, throw. That's what it's there for. The object isn't constructed and the client (who passed in the erroneous pointer) is properly told so.
If you want check that your class accept as arguments only std::string
and const char[] you can write something like this:
class Foo {
public:
template<typename U>
Foo(U &&val, typename std::enable_if<std::is_same<typename std::remove_reference<U>::type, std::string>::value ||
std::is_array<typename std::remove_reference<decltype(val)>::type>::value, void>::type* = nullptr): field_(val) {}
private:
std::string field_;
};
Then:
Foo foo("aa");//accept
std::string str("bb");
Foo foo2(str);//accept
Foo fnull(NULL);//compile time error
of course this solution not work if you want pass just pointer to char.

Rely on boolean value to access pointers

I have a class called MyClass that contains a pointer to an object, like so:
class MyClass {
public:
MyClass() : _blob(nullptr) {}
~MyClass() { free(); }
void generate() {
if(!_blob)
_blob = new Blob;
}
void free() {
if(_blob) {
delete _blob;
_blob = nullptr;
}
}
Blob* getBlob() { return _blob; }
private:
Blob *_blob;
};
The reason why it holds a pointer to a heap allocated object and doesn't contain it on the stack is because some MyClass instances don't allocate data for this object, therefore before accessing it I need to check if it's not a null pointer:
if(myClass->getBlob())
myClass->getBlob()->doSomething();
Now I had this idea to store a bool variable called _hasBlob and then use it like this
if(myClass->hasBlob())
myClass->getBlob()->doSomething();
Is this considered faster and legit? Or is it considered bad practice because I can see the danger potential of somehow ending up dereferencing a nullptr.
It's legit but redundant. It's not faster. Infact, while the check itself is as fast, maintaining the boolean in sync with the validity of the pointer is marginally slower. The worst thing about it is the maintenance burden of proving that the boolean is always in sync. Once it's implemented and proven correct though, it's just redundant and a waste of memory.
In general, you would expect MyClass::getBlob() to always give you a valid object whenever you ask for it. So in general my suggestion would be to implement that method as follows:
Blob* getBlob() {
if(_blob == nullptr) {
_blob = new Blob;
// Or call private method generateBlob, if there is a lot of logic
}
return _blob;
}
Alternatively, if default-constructed Blobs are small and you don't have thouasands of MyClass instances, you could just create the Blob object in the constructor and have getBlob return a reference, so you never have to check anything once you have a valid MyClass object.
If you want to avoid this automatic creation of Blob objects, you could add a hasBlob check, but instead of keeping a separate boolean, I would just implement it as
bool hasBlob() const { return _blob != nullptr; }
This function is almost certain to be inlined, doesn't cost you any extra storage, and it guarantees the correct result (for instance, it can never happen that you set _hasBlob = true and then fail to allocate a Blob). As you say, there is still a risk of dereferencing a null pointer, but as you have clearly documented (hopefully) that getBlob may return a null pointer if there is no Blob allocated for this instance, that risk is now with the caller and they should take care to check the result, as with any function returning a pointer. In fact, this solution is exactly equivalent to the code you already had, since if(myObject->getBlob()) now does exactly the same check as if(myObject->hasBlob()) would -- the only difference being that perhaps the latter is slightly more self-documenting.
Since you indicate in the comments that you are worried about the performance: I suspect that checking a pointer against null is fairly fast, but as usual, if you want to be sure, the usual advice of "Measure it!" holds. For example, you may find that because of the extra check in my first version of getBlob the compiler will not inline the function.

How to declare a function which creates an object which will never be null?

I have a function which creates an object QMenu (in heap)
QMenu* createMenu(QWidget* parent); // parent will takes ownership of the menu
The function will never return a null pointer. But I think the declaration don't tell the point because it returns a pointer. Thus when using the method, I need
if (QMenu* m = createMenu(parent))
m->...
which is annoying. If it returns a reference, it tells the point.
QMenu& createA(QWidget* parent);
I never see code declares this way. Is this okay? Is there any better declaration for the point?
Just document that it doesn't return null. Not exactly very high-tech as a solution, but you'll see that it works great in practice.
Since it's then clear that your function doesn't return null, you don't have to write:
if (QMenu* m = createMenu(parent))
m->...
You just write:
QMenu* m = createMenu(parent);
m->...
Think about it: either you need the if check in some form -- but then it's not true that the function never returns null.
Or the function really never, ever returns null. Then the if check is useless.
That being said, you can still add an assertion there to be extra safe:
QMenu* m = createMenu(parent);
assert(m != nullptr); // if you use C++11; otherwise assert(m != 0);
m->...
This means as much as "If m is null, then my own code is messed up and the program is wrong. If that happens, please quit the program ASAP!"
Yes, it's fine to return a created object by reference, if the function makes its own arrangements for ownership of that object's lifetime.
One big example of a function that does this: V& std::map<K,V>::operator[](const K&);.
The simplest and clearest way would be to return a value:
A createA();
Usually, if you need to allocate resources on "the heap", a good strategy is to design A such that it handles those resources itself.

return by reference or pointer and check for null?

I have a class :
class A
{
private:
vector<int> x;
public:
const vector<int>& immutable_data() {
return x;
}
vector<int>* mutable_data() {
return &x;
}
}
Now if i use this class , in my code , do i have to check if the pointer returned by the mutable_data() is null or not (given that i know the structure of this class). Personally i think i don't have to because i know there exist a secondary api which returns a const reference and so my pointer can never be null (I can't imagine of a scenario where this function would return me null ,even if it somehow does returns null, what would be the behavior of the const ref version in that case). Or should i say that i know its an address of an existing object on stack , so it cannot be null ? Is this the correct way to think or reason about this ? If any one thinks the other way , please give some example code.
For a more common case scenario in production code : if i use protocol buffers , i already know the generated code for my message templates (for eg: repeatedfields which are like stl containers), but do i still need to do null check every time i want to use the mutable api because they always return either by pointer or const reference.
returning by reference is not what i am looking for.
do i have to check if the pointer returned by the mutable_data() is null or not (given that i know the structure of this class)
In general, design elements like "have to check the pointer" depends on one of two things:
Does your design need to be provably safe?
If not, then does the design of A::mutable_data() dictate that it won't return null?
If (1), then you should invest in the kind of SAT-solver based tools which can test statically that your code won't access invalid memory.
If (2), I recommend that you consider the concept of Design by Contract -- it is a powerful one. If A::mutable_data()'s interface is specified not to return null, then it returning null would be a design defect in A::mutable_data().
Returning a null pointer usually means "I don't have any data for you". If the class will always have data, then, by design, the function will never return a null pointer. If that's the case, then code that uses the function does not need to check for null pointers. That's one of the guarantees that the function makes: "I won't ever return a null pointer".