Исключение unordered_map.find в C ++ 11 - PullRequest
0 голосов
/ 25 января 2019

последний упрощенный код, сбой при вызове emplace: программа получила сигнал SIGSEGV, ошибка сегментации.

#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <unordered_map>
#include <set>
#include <algorithm>

using namespace std;
struct test
{
    int x;
    int *y;
    map<string, uintptr_t> m;
};

int main ()
{

    int x=11,y=22;
    void *x1 = &x, *y1=&y;

    test *t1 = static_cast<test*>(calloc(1,sizeof(test)));
    t1->m.emplace(string("x"),reinterpret_cast<std::uintptr_t>(x1));
    t1->m.emplace(string("y"),reinterpret_cast<std::uintptr_t>(y1));

  return 0;
}

================ ниже приведен предыдущий кодcrash =====

C ++ 11 unordered_map находить вызовы throws: Программа завершена с сигналом 8, арифметическое исключение.изменено вокруг void * и uintptr_t в коде Linux C ++.Тип uintptr_t для меня приведен к / от указателя void * по причине истории.

unordered_map<string, uintptr_t> channels;
...
auto itr = channels.find(string("abc"));

Сбой при первом вызове, когда карта пуста.Это компилируется.Дамп GDB:

(gdb) bt
#0  0x000000000047457d in std::__detail::_Mod_range_hashing::operator() (this=0x2ad198001aa0, __num=8205015523586275093, __den=0)
    at /usr/include/c++/4.8.2/bits/hashtable_policy.h:345
#1  0x0000000000474c83 in std::__detail::_Hash_code_base, std::__detail::_Select1st, std::hash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>::_M_bucket_index (
    this=0x2ad198001aa0, __c=8205015523586275093, __n=0) at /usr/include/c++/4.8.2/bits/hashtable_policy.h:1108
#2  0x000000000047493a in std::_Hashtable, std::allocator >, std::__detail::_Select1st, std::equal_to, std::hash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits >::_M_bucket_index (this=0x2ad198001aa0, __k="nuance90-mrcp1", __c=8205015523586275093) at /usr/include/c++/4.8.2/bits/hashtable.h:593
#3  0x00000000004747b0 in std::_Hashtable, std::allocator >, std::__detail::_Select1st, std::equal_to, std::hash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits >::find (this=0x2ad198001aa0, __k="nuance90-mrcp1") at /usr/include/c++/4.8.2/bits/hashtable.h:1024
#4  0x00000000004745f5 in std::unordered_map, std::equal_to, std::allocator > >::find (this=0x2ad198001aa0, __x="abc")
    at /usr/include/c++/4.8.2/bits/unordered_map.h:543

1 Ответ

0 голосов
/ 25 января 2019

Я думаю, что нашел ответ: c функция calloc даст вам фиксированный размер памяти, если у вас есть контейнер STL внутри ac struct, и использовала функцию c calloc, программа не сможет увеличить размер.Вот код, который сработал, пожалуйста, посмотрите на разницу: содержимое STL внутри ac struct теперь становится указателем.

#include <utility>      // std::pair, std::make_pair
#include <string>       // std::string
#include <iostream>     // std::cout
#include <map>
#include <unordered_map>
#include <set>
#include <algorithm>

using namespace std;
struct test
{
    int x;
    int *y;
    map<string, uintptr_t> *m;
};

int main ()
{
    int x=11,y=22;
    void *x1 = &x, *y1=&y;

    test *t1 = static_cast<test*>(calloc(1,sizeof(test)));
    t1->m = new map<string, uintptr_t>();
    t1->m->emplace(string("x"),reinterpret_cast<std::uintptr_t>(x1));
    t1->m->emplace(string("y"),reinterpret_cast<std::uintptr_t>(y1));

    cout<<"====== retrive the map in a calloc memory area==="<<endl;
    auto itr = t1->m->find(string("x"));
    if(itr != t1->m->end())
    {
        int *i = reinterpret_cast<int*>(itr->second);
        cout<<"found x="<<*i<<endl;
    }

  return 0;
}
...