The difference in the implementation of malloc and new. Stack implementation?

When allocating memory, the new operator throws an exception if memory is not available. On the other hand, malloc returns NULL. What is the reason for the difference in implementation. In addition, when allocating static memory, that is, on the stack, is there an exception if we run out of memory?

I already followed the link What is the difference between the new / delete and malloc / free? but did not receive an answer to the difference in the implementation of the two

+4
source share
5 answers

The problem with C code is that you have to check the return value of the function to make sure that they work correctly. But a lot of code was written that did not check the return value and, as a result, exploded very well when you least expected it.

In the worst case, it doesn't even work right away, but continues to interrupt a memory failure at some point miles downstream of the error.

Thus, exceptions were born in C ++.
Now that there is an error, the code does not continue (thus, memory is not corrupted), but unwinds the stack (potentially forcing the application to exit). If you handle this problem, you must explicitly add code to deal with the situation before proceeding. Thus, you cannot accidentally forget not to check the error state; You either check this, or the application closes.

Using the new is consistent with this design.
If you fail to allocate memory, you must explicitly handle the error.
You cannot forget to check the NULL pointer. Thus, you cannot go and ruin the memory by accidentally using the NULL pointer.

In addition, when allocating static memory, that is, on the stack, is there an exception if we run out of memory?

Unfortunately, you cannot rely on this.
The implementation is determined by what happens when the stack overflows. On many systems, it is not even possible to detect a situation leading to memory corruption and, possibly, to the end of a failure.

Note

If you #include <new> then there is no new version of the cast that you can use that returns NULL when there is no remaining memory. This is best avoided unless you have a specific need.

+5
source

malloc cannot throw an exception because it will violate C compatibility. new throws an exception because this is the preferred way to report errors in C ++.

As far as I know, in early versions of C ++ new really returned 0 on failure,

+2
source

One important difference, I believe, is that:

  • malloc is a C-image of memory allocation; and exceptions in C
  • new is C ++, object-oriented and that’s it, the way; and in C ++ there are exceptions, and their use is cleaner.


Why store malloc in C ++? I suppose because the C ++ compiler can also work with C code ...

... But I often heard (from teachers, while still at school, a couple of years ago) that using malloc in C ++ is not recommended, and new should be used instead.

+1
source

In danger, perhaps add some confusion ...

  • malloc is a regular C function. Since this is C, it can only signal errors in ways that fit into a C program: using the return value, the argument passed by the pointer, or a global variable (for example, errno ).
  • new introduces a C ++ expression, it calls operator new to get the memory, and then constructs the object. Either operator new , or constructors can throw.

Note: no version of throw expression new

Most operator new are usually implemented in terms of malloc , but, as I have already noted, the expression new more than just getting memory, because it also creates object (s).

He also takes care of managing until he releases it to you. That is, if the constructor throws away, then it allocates the allocated memory correctly, and in the case of the expression new[] (which builds the array), it calls the destructor of those objects that have already been built.

Relative: it depends on your compiler and your operating system. The OS may flag a problem and signal an error, the compiler can check, etc.

Note that gcc introduces the split-stack option for compilation, which consists in distributing the minimum stack and then expanding it on demand. This neatly circumvents the problem of possible stack overflows, but introduces another binary compatibility problem, since interacting with code that was not built with this option can become foggy; I do not know how they plan to implement this.

+1
source

For completeness, remember also that you can model the old (non-throwing) method with nothrow - this is especially suitable for the critical parts of your code:

 // never throws char* ptr = new (nothrow) char [1024*1024]; // check pointer for succeeded allocation if ( !ptr ) { ... // handle error } 
0
source

Source: https://habr.com/ru/post/1341412/


All Articles