Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User-defined operator new that returns null pointer

I know that quite few C++ FAQs out there (and answers here on SO) say that there's no need to check the return value of a plain new-expression for null, since plain new-expression indicates failures by throwing exceptions. They basically state that plain new-expression never returns null. (By "plain new-expression" I mean a new-expression that is not a nothrow one).

However, despite this looking like a very basic question, I suddenly realized that I don't understand what specific assumptions they make (if any) when they give that answer.

In particular, I wonder if am I allowed to overload the basic plain form of ::operator new to always return null pointer, and therefore expect that all plain new-expressions that use that operator will now return null pointers as well.

According to the language specification, if my ::operator new is declared as non-throwing, then I may/shall indicate memory allocation failure by returning a null pointer. So, let's do just that

void *operator new(size_t s) throw() {
  return 0;
}

int main() {
  int *i = new int;
}

In my experiments, the above new-expression does successfully return a null pointer. So, am I breaking any rules in the above code or not? Is it legal to declare a plain ::operator new as non-throwing?

And if the above code is fine, then I'd presume that when someone states that a plain new "never returns null pointer", they do that under assumption that the standard-library-provided version of ::operator new has not been replaced. Is that presumption correct?

like image 854
AnT Avatar asked Oct 29 '14 01:10

AnT


People also ask

Can new operator return NULL?

On a standards-conforming C++ implementation, no. The ordinary form of new will never return NULL ; if allocation fails, a std::bad_alloc exception will be thrown (the new (nothrow) form does not throw exceptions, and will return NULL if allocation fails).

Can you return NULL in a pointer function?

A function that returns pointer values can return a null pointer when it is unable to perform its task. (A null pointer used in this way is analogous to the EOF value that functions like getchar return.) The start pointer steps over each character position in the input string.

What is :: operator new?

The new operator invokes the function operator new . For arrays of any type, and for objects that aren't class , struct , or union types, a global function, ::operator new , is called to allocate storage. Class-type objects can define their own operator new static member function on a per-class basis.

How do I return a NULL reference?

Use Nullable Reference Types If the developer really needs to return a null value from the method (in 99% of cases this is not necessary), the return type can be marked as a nullable reference type (the feature was introduced in C# 8.0).


1 Answers

The operators you can replace are as follows

[replacement.functions]

(2.1) — operator new(std::size_t)
(2.2) — operator new(std::size_t, const std::nothrow_t&)
(2.3) — operator new[](std::size_t)
(2.4) — operator new[](std::size_t, const std::nothrow_t&)
(2.5) — operator delete(void*)
(2.6) — operator delete(void*, const std::nothrow_t&)

void *operator new(size_t s) throw() is invalid, it has to throw in case of error

[new.delete.single]

void* operator new(std::size_t size);

3 Required behavior: Return a non-null pointer to suitably aligned storage (3.7.4), or else throw a bad_alloc exception. This requirement is binding on a replacement version of this function.

You can however safely replace the non-throwing noexcept overloads with a function that always returns null, as whoever calls these overloads must be aware of this behavior and check the return value accordingly. Obviously they won't be called unless the nothrow tag is passed, i.e. int* i = new (std::nothrow) int;

void* operator new(std::size_t size, const std::nothrow_t&) noexcept;

7 Required behavior: Return a non-null pointer to suitably aligned storage (3.7.4), or else return a null pointer. This nothrow version of operator new returns a pointer obtained as if acquired from the (possibly replaced) ordinary version. This requirement is binding on a replacement version of this function.

like image 92
user657267 Avatar answered Sep 22 '22 02:09

user657267