Binu
Binu

Reputation: 157

memory allocation failure during map/unordered_map insertion

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

Answers (1)

Adrian Mole
Adrian Mole

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

Related Questions