Reputation: 157
I am unable to capture a failure to allocate memory when inserting into a map, which results in a crash due to a segmentation fault.
struct Data
{
int64_t arr[100000000000000000]; // Large data to cause allocation failure
};
typedef unordered_map<int64_t, Data> UOM;
int main()
{
//void* p = malloc(sizeof(int64_t)*100000000000000000);
//void* p = new int64_t [100000000000000000];
//cout <<p <<endl;
UOM m;
try
{
m[1];
} catch(...)
{
}
}
If we used malloc it would return a NULL whereas new throws std::bad_alloc which can be caught. However, the insert into map which would need to allocate this memory just crashes (with a segmentation fault).
why is this the case and what should be behaviour as per standards?
EDIT: The platform, compiler are: Old compiler g++ 4.7.1 with "-std=c++11" flag on Redhat 6.10. Yeah we live in stone age!
Upvotes: 3
Views: 804
Reputation: 51835
You are attempting to create the m
object (and thus causing a bad_alloc
error) outside of your try ... catch
block. Move the try
'back' one level and you'll catch the exception:
int main()
{
try {
UOM m;
m[1];
}
catch (...) {
std::cout << "Caught!" << std::endl;
}
return 0;
}
EDIT: Note also that the following catches the exception at creation (with clang-cl, full optimization):
int main()
{
UOM* m;
try {
m = new UOM;
}
catch (...) {
std::cout << "Caught at creation!" << std::endl;
return 0;
}
try {
(*m)[1];
}
catch (...) {
std::cout << "Caught at insertion!" << std::endl;
}
delete m;
return 0;
}
EDIT #2: This is possibly implementation-defined behaviour for the default constructor of std::unordered_map
, as indicated on cppreference:
(1) Constructs empty container. Sets max_load_factor() to 1.0. For the default constructor, the number of buckets is implementation-defined.
Upvotes: 2