Vishal Sharma
Vishal Sharma

Reputation: 1750

How to safely use unique_ptr with functions which can return NULL?

I've noticed that this compiles:

#include<memory>
#include<iostream>
using namespace std;
int main()
{
    unique_ptr<int>a(nullptr);
    if(!a)
    cout<<"NULLPTR";
}

However, this doesn't:

#include<memory>
#include<iostream>
using namespace std;
int main()
{
    unique_ptr<int>a(NULL);
    if(!a)
    cout<<"NULL";
}

I'm working with a library which has several functions which return a raw pointer and those have to be manually freed after their use. I want to use unique_ptr(with custom deleter) to manage such raw pointers. I was worried about those cases when those functions return NULL as I think that might cause some problems.

Upvotes: 1

Views: 130

Answers (2)

n. m. could be an AI
n. m. could be an AI

Reputation: 119877

NULL is an obsolete null pointer constant that is deprecated in favor of nullptr. Both constants designate the same thing, a null pointer value. These constants are compile time constructs.

NULL is deprecated because apart from designating a null pointer value, it also designates the integer zero, depending on context. (It is a macro defined as 0). This is dangerous and error prone, so unique_ptr specifically disallows it.

At run time, a function cannot possibly return a null pointer constant, which belongs to a totally wrong category of things. It returns a null pointer value. At that time, there is neither NULL nor nullptr.

Upvotes: 3

Nikos C.
Nikos C.

Reputation: 51840

That's fine. It's just the NULL macro (which expands to just 0 on most compilers) that's causing the problem. 0 matches both the nullptr_t and T* constructors of unique_ptr, so it's ambiguous and won't compile.

When initializing a unique_ptr with a pointer variable or the return value of a function, it doesn't matter whether nullptr, NULL or 0 was used. They all have the same effect: a null pointer:

This is perfectly fine, for example

int* int_p1 = NULL;
int* int_p2 = (int*)malloc(sizeof(int));

unique_ptr<int, decltype(&free)> a1(int_p1, free);
unique_ptr<int, decltype(&free)> a2(int_p2, free);

Note: if you're not interfacing with C functions that used malloc() to allocate, but with C++ functions that used new, do not use custom deleters. The default deleter of unique_ptr already uses delete.

Upvotes: 5

Related Questions