提问者:小点点

map/unordered_map插入期间内存分配失败


当插入到映射中时,我无法捕获分配内存的失败,并以seg 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(...)
    {
    }
}

如果我们使用malloc,它将返回一个NULL,而new抛出std::bad_alloc,这可以被捕获。 但是,需要分配这个内存的insert into map就会崩溃。

为什么会出现这种情况?根据标准,行为应该是什么?

编辑:平台,编译器是:在Redhat 6.10上带有“-std=C++11”标志的旧编译器G++4.7.1。 是啊,我们生活在石器时代!


共1个答案

匿名用户

您试图在Try...Catch块之外创建M对象(从而导致BAD_ALLOC错误)。 将try“后移”一级,您将捕获异常:

int main()
{
    try {
        UOM m;
        m[1];
    }
    catch (...) {
        std::cout << "Caught!" << std::endl;
    }
    return 0;
}

编辑:还要注意,以下内容捕获了创建时的异常(使用clang-cl,完全优化):

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;
}

编辑#2:这可能是std::unordered_map的默认构造函数的实现定义行为,如CPPreference所示:

(1)构造空容器。 将max_load_factor()设置为1.0。 对于默认构造函数,桶的数量是由实现定义的。