I have written the following code in VScode c++
When I input a really large integer number for n (for example 1000000000000000) I want this output:
"Dynamic memory allocation failed.nProgram will terminate."
If I run the code in VScode with g++ compiler that output is never shown.
However, when I run it in an online compiler like Programiz, the output I want is shown.
The program is as follows:
#include <iostream>
#include <new>
int main(){
long int n;
std::cout << "give n : ";
std::cin >> n;
int* a= new (std::nothrow) int[n]; // I expect new to return nullptr
// if the allocation fails
if (!a) {
std::cout << "Dynamic memory allocation failed.nProgram will terminate.";
return -1;
}
return 0;
}
So what is the problem?
As I said, in an online compiler when I input for example 1000000000000000 as the value for the integer n the output is the desired:
give n : 1000000000000000
Dynamic memory allocation failed.
Program will terminate.
=== Code Exited With Errors ===
but in VScode the output is :
if ($?) { g++ test.cpp -o test } ; if ($?) { .test }
give n : 1000000000000000
terminate called after throwing an instance of 'std::bad_array_new_length'
what(): std::bad_array_new_length
What can I do to fix this?
the problem is that I want the program to cout that the dynamic memory allocation failed if the user gives such a huge number for the integer n
I use the GCC C++ compiler (g++) and GDB debugger from mingw-w64.
I downloaded VScode version 1.92 and followed the instructions from their site https://code.visualstudio.com/docs/cpp/config-mingw.
3
Answers
From as-if rule
so, we might consider that
int* a = new (std::nothrow) int[n];
always succeed.resulting in program
You might see here that clang optimize out the allocation (and didn’t output message) whereas gcc doesn’t optimize and do the call, and so, print the message.
You cannot rely on
new
returningnullptr
if the allocation goes wrong, at least not on recent standard compliant C++ implementations (not sure which standard actually), and(std::nothrow)
apparently has no effect non your implementation.Instead you should catch and handle exceptions like this:
Another possibility, maybe more convenient for your use case, is using
std::set_new_handler
:As soon as
new
goes wrong,newhandler()
will be called, which takes care of displaying your error message and then quits using theexit
function.If you are on Windows, then
long int n
is a 32-bit integral value, or you build a 32-bit application on other platforms. When you enter1000000000000000
you get the integer overflow and the negative value-1530494976
inn
.new int[n]
with a negative value throwsstd::bad_array_new_length
. Note, this exception is not what is disabled bystd::nothrow
operator new
overload.https://godbolt.org/z/sf4GKszKd
Update the declaration
long long n
oruint64_t n
after#include <cstdint>
.