C++, new vs malloc return value - c++

When I learnt C99 I was told to Always check the return value of malloc to check whether it succeeded or failed, but now I started learning C++ and I was told that there is no need to do this with the keyword new, and you can suppose that it will always work for you.
But why is that?

new can still fail and throw an std::bad_alloc exception, and your program needs to may check whether it did, or simply let the exception propagate up. There is also a flag you can pass to new to make it act like malloc and return NULL on error. Take a look at the documentation.
Edit
Here are two examples:
try {
char* arr = new char[20];
} catch (std::bad_alloc& e) {
// Handle error
}
Or using the nothrow flag, making new act like malloc:
char* arr = new (std::nothrow) char[20];
if (!arr) {
// Handle error
}

Any dynamic allocation can fail.
malloc signals this by returning NULL. If it failed, unless explicitly you check for its return the program will continue, even though malloc failed, most likely resulting in Undefined Behavior when you try to access via the pointer returned by malloc (which is NULL). This is why you should always check for malloc failure.
new on the other hand signals this by throwing an std::bad_alloc exception (default behavior). If you don't catch the the exception it will bubble up to the top and terminate your program. This is desired, so you don't need to do anything.
Also please note that in C++ you should never explicitly call new/delete. Use standard containers like std::vector or smart pointers.

New allocates memory and calls constructor for object initialization: if it fails it throws an exception std::bad_alloc. malloc allocates memory and does not call constructor: if its allocation fails, it return a null pointer, so you have to check what you get from it.
However, in c++ you cannot assume that new will always work: you can assume that if it doesn't work, it throws an exception.

There are many ways to check the return values,
you could check the returned pointer if you use the nothrow version
you can use a try block on a much higher level
you can use the set_new_handler to check handle it for all new's.
I prefer the 2nd and 3rd.

In C++, unless you use advanced features, if memory cannot be allocated with the new operator, an exception is thrown, so the there is no need to check if the pointer obtained by new is null or not. Handling the exception is up to the programmer. If you don't, the program will terminate abruptly. It is actually tricky to handle this exception properly and restart the operations without memory or resource leaks, which is why allocation of objects with new and delete is now considered obsolete. Using containers and smart pointers is a better alternative.
Note that you can get the same behavior in C with a wrapper on malloc():
#include <stdio.h>
#include <stdlib.h>
void *xmalloc(size_t size) {
void *p = malloc(size);
if (p == NULL) {
fprintf(stderr, "malloc failed for %zu bytes\n", size);
exit(1);
}
return p;
}
There is no need to check for memory allocation failure by xmalloc() since such a failure causes an abrupt program termination automatically. This approach can be used for command line utilities where failure is not catastrophic and can be handled interactively.

Related

Exceptions on unique_ptr and make_unique [duplicate]

There is a method called foo that sometimes returns the following error:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Abort
Is there a way that I can use a try-catch block to stop this error from terminating my program (all I want to do is return -1)?
If so, what is the syntax for it?
How else can I deal with bad_alloc in C++?
In general you cannot, and should not try, to respond to this error. bad_alloc indicates that a resource cannot be allocated because not enough memory is available. In most scenarios your program cannot hope to cope with that, and terminating soon is the only meaningful behaviour.
Worse, modern operating systems often over-allocate: on such systems, malloc and new can return a valid pointer even if there is not enough free memory left – std::bad_alloc will never be thrown, or is at least not a reliable sign of memory exhaustion. Instead, attempts to access the allocated memory will then result in a segmentation fault, which is not catchable (you can handle the segmentation fault signal, but you cannot resume the program afterwards).
The only thing you could do when catching std::bad_alloc is to perhaps log the error, and try to ensure a safe program termination by freeing outstanding resources (but this is done automatically in the normal course of stack unwinding after the error gets thrown if the program uses RAII appropriately).
In certain cases, the program may attempt to free some memory and try again, or use secondary memory (= disk) instead of RAM but these opportunities only exist in very specific scenarios with strict conditions:
The application must ensure that it runs on a system that does not overcommit memory, i.e. it signals failure upon allocation rather than later.
The application must be able to free memory immediately, without any further accidental allocations in the meantime.
It’s exceedingly rare that applications have control over point 1 — userspace applications never do, it’s a system-wide setting that requires root permissions to change.1
OK, so let’s assume you’ve fixed point 1. What you can now do is for instance use a LRU cache for some of your data (probably some particularly large business objects that can be regenerated or reloaded on demand). Next, you need to put the actual logic that may fail into a function that supports retry — in other words, if it gets aborted, you can just relaunch it:
lru_cache<widget> widget_cache;
double perform_operation(int widget_id) {
std::optional<widget> maybe_widget = widget_cache.find_by_id(widget_id);
if (not maybe_widget) {
maybe_widget = widget_cache.store(widget_id, load_widget_from_disk(widget_id));
}
return maybe_widget->frobnicate();
}
…
for (int num_attempts = 0; num_attempts < MAX_NUM_ATTEMPTS; ++num_attempts) {
try {
return perform_operation(widget_id);
} catch (std::bad_alloc const&) {
if (widget_cache.empty()) throw; // memory error elsewhere.
widget_cache.remove_oldest();
}
}
// Handle too many failed attempts here.
But even here, using std::set_new_handler instead of handling std::bad_alloc provides the same benefit and would be much simpler.
1 If you’re creating an application that does control point 1, and you’re reading this answer, please shoot me an email, I’m genuinely curious about your circumstances.
You can catch it like any other exception:
try {
foo();
}
catch (const std::bad_alloc&) {
return -1;
}
Quite what you can usefully do from this point is up to you, but it's definitely feasible technically.
What is the C++ Standard specified behavior of new in c++?
The usual notion is that if new operator cannot allocate dynamic memory of the requested size, then it should throw an exception of type std::bad_alloc.
However, something more happens even before a bad_alloc exception is thrown:
C++03 Section 3.7.4.1.3: says
An allocation function that fails to allocate storage can invoke the currently installed new_handler(18.4.2.2), if any. [Note: A program-supplied allocation function can obtain the address of the currently installed new_handler using the set_new_handler function (18.4.2.3).] If an allocation function declared with an empty exception-specification (15.4), throw(), fails to allocate storage, it shall return a null pointer. Any other allocation function that fails to allocate storage shall only indicate failure by throw-ing an exception of class std::bad_alloc (18.4.2.1) or a class derived from std::bad_alloc.
Consider the following code sample:
#include <iostream>
#include <cstdlib>
// function to call if operator new can't allocate enough memory or error arises
void outOfMemHandler()
{
std::cerr << "Unable to satisfy request for memory\n";
std::abort();
}
int main()
{
//set the new_handler
std::set_new_handler(outOfMemHandler);
//Request huge memory size, that will cause ::operator new to fail
int *pBigDataArray = new int[100000000L];
return 0;
}
In the above example, operator new (most likely) will be unable to allocate space for 100,000,000 integers, and the function outOfMemHandler() will be called, and the program will abort after issuing an error message.
As seen here the default behavior of new operator when unable to fulfill a memory request, is to call the new-handler function repeatedly until it can find enough memory or there is no more new handlers. In the above example, unless we call std::abort(), outOfMemHandler() would be called repeatedly. Therefore, the handler should either ensure that the next allocation succeeds, or register another handler, or register no handler, or not return (i.e. terminate the program). If there is no new handler and the allocation fails, the operator will throw an exception.
What is the new_handler and set_new_handler?
new_handler is a typedef for a pointer to a function that takes and returns nothing, and set_new_handler is a function that takes and returns a new_handler.
Something like:
typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();
set_new_handler's parameter is a pointer to the function operator new should call if it can't allocate the requested memory. Its return value is a pointer to the previously registered handler function, or null if there was no previous handler.
How to handle out of memory conditions in C++?
Given the behavior of newa well designed user program should handle out of memory conditions by providing a proper new_handlerwhich does one of the following:
Make more memory available: This may allow the next memory allocation attempt inside operator new's loop to succeed. One way to implement this is to allocate a large block of memory at program start-up, then release it for use in the program the first time the new-handler is invoked.
Install a different new-handler: If the current new-handler can't make any more memory available, and of there is another new-handler that can, then the current new-handler can install the other new-handler in its place (by calling set_new_handler). The next time operator new calls the new-handler function, it will get the one most recently installed.
(A variation on this theme is for a new-handler to modify its own behavior, so the next time it's invoked, it does something different. One way to achieve this is to have the new-handler modify static, namespace-specific, or global data that affects the new-handler's behavior.)
Uninstall the new-handler: This is done by passing a null pointer to set_new_handler. With no new-handler installed, operator new will throw an exception ((convertible to) std::bad_alloc) when memory allocation is unsuccessful.
Throw an exception convertible to std::bad_alloc. Such exceptions are not be caught by operator new, but will propagate to the site originating the request for memory.
Not return: By calling abort or exit.
I would not suggest this, since bad_alloc means you are out of memory. It would be best to just give up instead of attempting to recover. However here is is the solution you are asking for:
try {
foo();
} catch ( const std::bad_alloc& e ) {
return -1;
}
I may suggest a more simple (and even faster) solution for this. new operator would return null if memory could not be allocated.
int fv() {
T* p = new (std::nothrow) T[1000000];
if (!p) return -1;
do_something(p);
delete p;
return 0;
}
I hope this could help!
Let your foo program exit in a controlled way:
#include <stdlib.h> /* exit, EXIT_FAILURE */
try {
foo();
} catch (const std::bad_alloc&) {
exit(EXIT_FAILURE);
}
Then write a shell program that calls the actual program. Since the address spaces are separated, the state of your shell program is always well-defined.
Of course you can catch a bad_alloc, but I think the better question is how you can stop a bad_alloc from happening in the first place.
Generally, bad_alloc means that something went wrong in an allocation of memory - for example when you are out of memory. If your program is 32-bit, then this already happens when you try to allocate >4 GB. This happened to me once when I copied a C-string to a QString. The C-string wasn't '\0'-terminated which caused the strlen function to return a value in the billions. So then it attempted to allocate several GB of RAM, which caused the bad_alloc.
I have also seen bad_alloc when I accidentally accessed an uninitialized variable in the initializer-list of a constructor. I had a class foo with a member T bar. In the constructor I wanted to initialize the member with a value from a parameter:
foo::foo(T baz) // <-- mistyped: baz instead of bar
: bar(bar)
{
}
Because I had mistyped the parameter, the constructor initialized bar with itself (so it read an uninitialized value!) instead of the parameter.
valgrind can be very helpful with such errors!

How to catch or handle segfault from free() or delete()

In c++, I have a server code running continuously 24*7 but i am getting segfault sometimes while freeing the buffer.
I tried try catch as well.
try {
free(partialBuf);
} catch (...) {
printf("Caught partial buf free error");
}
Thanks in advance!
Since you're apparently able to use try/catch, you're writing C++ code. It helps to know which language you're using.
The solution then is to use std::shared_ptr. You may have multiple places in which a pointer goes out of scope. With shared_ptr you no longer call free, and as a bonus shared_ptr will call delete only once (after the last pointer goes out of scope).
However, you should now allocate memory with new instead of malloc.
A segfault is not an exception in the sense of other C++ exceptions, hence you cannot catch it with try/catch. A segfault can have any number of reasons, but in 99.9% of cases it's a memory access bug :-) If the segfault happens during a call to delete or free(), chances are that you are having a double-free issue.
You could use GDB to debug, and find out whether you are trying to free a pointer which was not allocated previously.

Difference between using try-Catch exception handler and if else condition check? [duplicate]

This question already has answers here:
Is there a general consensus in the C++ community on when exceptions should be used? [closed]
(11 answers)
Closed 9 years ago.
I have used in many places if...else statements, however I'm new to exception handling. What is the main difference among these two?
for eg:
int *ptr = new (nothrow) int[1000];
if (ptr == NULL) {
// Handle error cases here...
}
OR
try
{
int* myarray= new int[1000];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
So we are using here standard class for exception which has some in build function like e.what(). So it may be advantage. Other than that all other functionality handling we can do using if...else also. Is there any other merits in using exception handling?
To collect what the comments say in an answer:
since the standardization in 1998, new does not return a null pointer at failure but throws an exception, namely std::bad_alloc. This is different to C's malloc and maybe to some early pre-standard implementations of C++, where new might have returned NULL as well (I don't know, tbh).
There is a possibility in C++, to get a nullpointer on allocation failure instead of an exception as well:
int *ptr = new(std::nothrow) int[1000];
So in short, the first code you have will not work as intended, as it is an attempt of C-style error handling in the presence of C++ exceptions. If allocation fails, the exception will be thrown, the if block will never be entered and the program probably will be terminated since you don't catch the bad_alloc.
There are lots of articles comparing general error handling with exceptions vs return codes, and it would go way to far trying to cover the topic here. Amongst the reasons for exceptions are
Function return types are not occupied by the error handling but can return real values - no "output" function parameters needed.
You do not need to handle the return of every single function call in every single function but can just catch the exception some levels up the call stack where you actually can handle the error
Exceptions can pass arbitraty information to the error handling site, as compared to one global errno variable and a single returned error code.
The main difference is that the version using exception handling at least might work, where the one using the if statement can't possibly work.
Your first snippet:
int *ptr = new int[1000];
if (ptr == NULL) {
// Handle error cases here...
}
...seems to assume that new will return a null pointer in case of failure. While that was true at one time, it hasn't been in a long time. With any reasonably current compiler, the new has only two possibilities: succeed or throw. Therefore, your second version aligns with how C++ is supposed to work.
If you really want to use this style, you can rewrite the code to get it to return a null pointer in case of failure:
int *ptr = new(nothrow) int[1000];
if (ptr == NULL) {
// Handle error cases here...
}
In most cases, you shouldn't be using new directly anyway -- you should really use std::vector<int> p(1000); and be done with it.
With that out of the way, I feel obliged to add that for an awful lot of code, it probably makes the most sense to do neither and simply assume that the memory allocation will succeed.
At one time (MS-DOS) it was fairly common for memory allocation to actually fail if you tried to allocate more memory than was available -- but that was a long time ago. Nowadays, things aren't so simple (as a rule). Current systems use virtual memory, which makes the situation much more complicated.
On Linux, what'll typically happen is that even the memory isn't really available, Linux will do what's called an "overdcommit". You'll still get a non-null pointer as if the allocation had succeeded -- but when you try to use the memory, bad things will happen. Specifically, Linux has what's called an "OOM Killer" that basically assumes that running out of memory is a sign of a bug, so if it happens, it tries to find the buggy program(s), and kills it/them. For most practical purpose, this means your program will probably be killed, and other (semi-arbitrarily chosen) ones may be as well.
Windows stays a little closer to the model C++ expects, so if (for example) your code were running on an unattended server, the allocation might actually fail. Long before it fails, however, it'll drag the rest of the machine to its knees, madly swapping in a doomed attempt at making the allocation succeed. If the user is actually operating the machine at the time, they'll typically either kill your program or else kill some others to free up enough memory for your code to get the requested memory fairly quickly.
In none of these cases is it particularly realistic to program against the assumption that an allocation can fail though. For most practical purposes, one of two things happens: either the allocation succeeds, or the program dies.
That leads back to the previous advice: in a typical case, you should generally just use std::vector, and assume your allocation will succeed. If you need to provide availability beyond that, you just about need to do it some other way (such as re-starting the process if it dies, preferably in a way that uses less memory).
As already mentioned, your original if-else example would still throw an exception from C++98 onwards, though adding nothrow (as edited) should make it work as desired (return null, thus trigger if-statement).
Below I'll assume, for simplicity, that, for if-else to handle exceptions, we have functions returning false on exception.
Some advantages of exceptions above if-else, off the top of my head:
You know the type of the exception for logging / debugging / bug fixing
Example:
When a function throws an exception, you can, to a reasonable extent, tell whether there may be a problem with the code or something that you can't do much about like an out of memory exception.
With the if-else, when a function returns false, you have no idea what happened in that function.
You can of course have separate logging to record this information, but why not just return an exception with the exception details included instead?
You needn't have a mess of if-else conditions to propagate the exception to the calling function
Example: (comments included to indicate behaviour)
bool someFunction() // may return false on exception
{
if (someFunction2()) // may return false on exception
return false;
if (someFunction3()) // may return false on exception
return false;
return someFunction4(); // may return false on exception
}
(There are many people who don't like having functions with multiple return statements. In this case, you'll have an even messier function.)
As opposed to:
void someFunction() // may throw exception
{
someFunction2(); // may throw exception
someFunction3(); // may throw exception
someFunction4(); // may throw exception
}
An alternative to, or extension of, if-else is error codes. For this, the second point will remain. See this for more on the comparison between that and exceptions.
If you handle the error locally, if ... else is cleaner. If the function where the error occurs doesn't handle the error, then throw an exception to pass off to someone higher in the call chain.
First of all your first code with if statement will terminate program in case of exception thrown by new[] operator because of not handled exception. You can check such thing here for example: http://www.cplusplus.com/reference/new/operator%20new%5B%5D/
Also exceptions are thrown in many other cases, not only when allocation failed and their main feature (in my eyes) is moving control in application up (to place where exception is handled). I recommend you read some more about exceptions, good read would be "More Effective C++" by Scott Meyers, there is great chapter on exceptions.

Who is responsible for delete?

I was analyzing a code and I am confused on a particular code.
I have posted the code/pseudo-code which will convey the same meaning.
Class 1
Class1::Func1()
{
Collection* cltn;
try
{
cltn = Class2::get_records_from_db();
}
catch(Informix error)
{}
catch(DB Error)
{}
catch(...)
{ Unknown exception } //I get this error always once the process processes lot of records
}
Class 2
Collection* Class2::get_records_from_db()
{
Collection *clt = new Collection();
try
{
//Query database
For each row in query result
Row *row = new row();
populate(row)
clt->add(*row)
...
if( Informix error)
{
throw Informix error;
}
}
catch(...)
{
delete clt; //Who will delete row?
clt = 0;
throw Db error
}
return clt; //Who will delete clt?
}
Problem - PART 2
Thanks for the insights on the first problem. Now here is the real problem which is happening.
Class 1 is a C++ process and Class 2 is a library which talks to Informix database.
Class2::get_records_from_db() is a function which queries an Informix DB and returns the result-set. I have enhanced the above code which is more similar to the real code.
Collection objects deals with 200k of row objects, which as most of you said is not released properly.
The caller is seeing "Unknown exception" in the general catch block. Can that be because of the huge memory leaks created in Class 2?
I also see some Informix errors 406 (Out of memory error) in the logs. The process core-dumps after spitting out a series of Unknown Exception & SQLERR406
I want to know whether the core dump is a byproduct of the memory leaks.
What is the problem with the code you presented?
The code example you present is a very bad and wrong code.
No one deletes either of (row and clt) them. This leads to a memory leak or a Undefined Behavior depending on whether their destructors have trivial or nontrivial implementation.Either way it means very bad things can happen.
If you allocate an object using new you need to explicitly deallocate it by calling delete on the pointer returned by new. Since you do not call delete on either of the pointers, they both are never deallocated at all.
Who should be responsible for delete?
The objects themselves!
The objects should have an inbuilt functionality to de-allocate themselves as soon as their scope({,}) ends. This way no one needs to explicitly deallocate any of the objects, but they get implicitly deleted once they are not needed anymore. This technique is popularly known as Resource Allocation is Initialization(RAII) or Scope Bound Resource Management(SBRM) in C++.
Each of your objects(row and clt) should be using a RAII by writing wrappers over these raw pointers or even better simply by using readily available Smart pointers.
Smart pointers are what you need. You should put each new Row into std::shared_ptr<Row> row instead of a pointer; those shared_ptrs will be automatically cleaned up when they go out of scope (eg, when the try-catch block exits).
What you should do with 'clt isn't quite so clear cut... I'd be tempted to store it in a std::unique_ptr<Collection> and return that because then it is clear that a) it will be automatically deleted at some point (potentially when your program exits) and b) it is clear to calling code that they now own the value returned by get_records_from_db(), not the Class2 instance (or singleton) that generated it.
Clear ownership semantics are a good thing.

Any pitfalls with allocating exceptions on the heap?

Question says it all: Are there any pitfalls with allocating exceptions on the heap?
I am asking because allocating exceptions on the heap, in combination with the polymorphic exception idiom, solve the problem of transporting exceptions between threads (for the sake of discussion, assume that I can't use exception_ptr). Or at least I think it does...
Some of my thoughts:
The handler of the exception will have to catch the exception and know how to delete it. This can be solved by actually throwing an auto_ptr with the appropriate deleter.
Are there other ways to transport exceptions across threads?
Are there any pitfalls with allocating exceptions on the heap?
One obvious pitfall is that a heap allocation might fail.
Interestingly, when an exception is thrown it actually throws a copy of the exception object that is the argument of throw. When using gcc, it creates that copy in the heap but with a twist. If heap allocation fails it uses a static emergency buffer instead of heap:
extern "C" void *
__cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) throw()
{
void *ret;
thrown_size += sizeof (__cxa_refcounted_exception);
ret = malloc (thrown_size);
if (! ret)
{
__gnu_cxx::__scoped_lock sentry(emergency_mutex);
bitmask_type used = emergency_used;
unsigned int which = 0;
if (thrown_size > EMERGENCY_OBJ_SIZE)
goto failed;
while (used & 1)
{
used >>= 1;
if (++which >= EMERGENCY_OBJ_COUNT)
goto failed;
}
emergency_used |= (bitmask_type)1 << which;
ret = &emergency_buffer[which][0];
failed:;
if (!ret)
std::terminate ();
}
}
So, one possibility is to replicate this functionality to protect from heap allocation failures of your exceptions.
The handler of the exception will have to catch the exception and know how to delete it. This can be solved by actually throwing an auto_ptr with the appropriate deleter.
Not sure if using auto_ptr<> is a good idea. This is because copying auto_ptr<> destroys the original, so that after catching by value as in catch(std::auto_ptr<std::exception> e) a subsequent throw; with no argument to re-throw the original exception may throw a NULL auto_ptr<> because it was copied from (I didn't try that).
I would probably throw a plain pointer for this reason, like throw new my_exception(...) and catch it by value and manually delete it. Because manual memory management leaves a way to leak memory I would create a small library for transporting exceptions between threads and put such low level code in there, so that the rest of the code doesn't have to be concerned with memory management issues.
Another issue is that requiring a special syntax for throw, like throw new exception(...), may be a bit too intrusive, that is, there may be existing code or third party libraries that can't be changed that throw in a standard manner like throw exception(...). It may be a good idea just to stick to the standard throw syntax and catch all possible exception types (which must be known in advance, and as a fall-back just slice the exception and only copy a base class sub-object) in a top-level thread catch block, copy that exception and re-throw the copy in the other thread (probably on join or in the function that extracts the other's thread result, although the thread that throws may be stand-alone and yield no result at all, but that is a completely another issue and we assume we deal with some kind of worker thread with limited lifetime). This way the exception handler in the other thread can catch the exception in a standard way by reference or by value without having to deal with the heap. I would probably choose this path.
You may also take a look at Boost: Transporting of Exceptions Between Threads.
There are two evident one:
One - easy - is that doing throw new myexception risk to throw a bad_alloc (not bad_alloc*), hence catch exception* doesn't catch the eventual impossible to allocate exception. And throwing new(nothrow) myexception may throw ... a null pointer.
Another - more a design issue - is "who has to catch". If it is not yourself, consider a situation where your client, that may also be a client of somebody else, has - depending on who's throwing - to decide if delete or not. May result in a mess.
A typical way to solve the problem is throwing a static variable by reference (or address): doesn't need to be deleted and doesn't require to be copied when going down in the unrolled stack
If the reason you're throwing an exception is that there's a problem with the heap (out of memory or otherwise) allocating your exception on the heap will just cause more problems.
There is another catch when throwing std::auto_ptr<SomeException>, and also boost shared pointers: while runtime_error is derived from exception, auto_ptr<runtime_error> is not derived from auto_ptr<exception>.
As a result, a catch(auto_ptr<exception> &) won't catch an auto_ptr<runtime_error>.