Ошибка сегментации при использовании функции «Назад» для вектора - PullRequest
0 голосов
/ 10 ноября 2019

Итак, я пытаюсь создать хеш-таблицу с пользовательской хеш-функцией с нуля, и я столкнулся с проблемой ошибки сегментации при тестировании функции вставки. Если я правильно прочитал вывод gdb, проблема возникла, когда я попытался отодвинуть логический вектор в моей функции wn_to_bool (берет целое число и преобразует его в вектор логических значений). Я пытался отладить эту проблему некоторое время, но не нашел решения. Любая помощь будет с благодарностью, я могу обновить пост с остальной частью кода, упомянутого в отладке, если это необходимо. Заранее спасибо.

Вывод GDB без нового оператора

Program received signal SIGSEGV, Segmentation fault.
0x000055555555668b in std::vector<bool, std::allocator<bool> >::push_back (this=0x0, __x=false) at /usr/include/c++/9.2.0/bits/stl_bvector.h:955
955             if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr())
(gdb) bt
#0  0x000055555555668b in std::vector<bool, std::allocator<bool> >::push_back (this=0x0, __x=false) at /usr/include/c++/9.2.0/bits/stl_bvector.h:955
#1  0x0000555555556302 in HashTable<int, int>::wn_to_bool (this=0x7fffffffe3f0, wn=2) at Data_Structures/Hash_Table.cpp:186
#2  0x0000555555556230 in HashTable<int, int>::hashfct (this=0x7fffffffe3f0, key=2) at Data_Structures/Hash_Table.cpp:146
#3  0x0000555555556163 in HashTable<int, int>::insert (this=0x7fffffffe3f0, key=2, value=3) at Data_Structures/Hash_Table.cpp:53
#4  0x0000555555555b0f in main (argc=1, argv=0x7fffffffe4f8) at main.cpp:16

Вывод GDB с новым оператором

Program received signal SIGABRT, Aborted.
0x00007ffff7ab8f25 in raise () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff7ab8f25 in raise () from /usr/lib/libc.so.6
#1  0x00007ffff7aa2897 in abort () from /usr/lib/libc.so.6
#2  0x00007ffff7b03758 in __malloc_assert () from /usr/lib/libc.so.6
#3  0x00007ffff7b05f6f in sysmalloc () from /usr/lib/libc.so.6
#4  0x00007ffff7b06d32 in _int_malloc () from /usr/lib/libc.so.6
#5  0x00007ffff7b07e84 in malloc () from /usr/lib/libc.so.6
#6  0x00007ffff7e47cba in operator new (sz=40) at /build/gcc/src/gcc/libstdc++-v3/libsupc++/new_op.cc:50
#7  0x000055555555633d in HashTable<int, int>::wn_to_bool (this=0x7fffffffe3f0, wn=2) at Data_Structures/Hash_Table.cpp:181
#8  0x0000555555556230 in HashTable<int, int>::hashfct (this=0x7fffffffe3f0, key=2) at Data_Structures/Hash_Table.cpp:146
#9  0x0000555555556163 in HashTable<int, int>::insert (this=0x7fffffffe3f0, key=2, value=3) at Data_Structures/Hash_Table.cpp:53
#10 0x0000555555555b0f in main (argc=1, argv=0x7fffffffe4f8) at main.cpp:16

функция wn_to_bool ( Обратите внимание, что изначально v - пустой вектор, поэтому функция вставки не будет работать )

template <typename K, typename V> std::vector<bool>* HashTable<K,V>::wn_to_bool(long wn)
{
    std::vector<bool>* v;

    while(wn != 0)
    {
        if(wn % 2 == 0)
            v->push_back(false);
        else
            v->push_back(true);

        wn = wn / 2;
    }

    return v; 
}

Ответы [ 2 ]

2 голосов
/ 10 ноября 2019

Обратите внимание, v изначально пустой вектор

Это не так. Это унифицированный указатель. Фактического вектора в поле зрения нет.

Не используйте необработанные указатели.

Оставляя утилиту такого функционала в стороне, вот способ написать ее.

template <typename K, typename V> 
std::vector<bool> // no pointer
HashTable<K,V>::wn_to_bool(long wn)
{
    std::vector<bool> v; //no pointer
    while(wn != 0)
    {
        if(wn % 2 == 0)
            v.push_back(false);
        else
            v.push_back(true);
        wn = wn / 2;
    }
    return v; 
}

, поэтому функция вставки не будет работать)

insert отлично работает с пустым вектором, например. vector<int> v; v.insert(v.begin(), 42).

1 голос
/ 10 ноября 2019

когда вы делаете std::vector<bool>* v, у вас будет неинициализированный указатель на std::vector<bool>. Это означает, что v имеет какое-то произвольное значение, не будучи назначенным никакому выделенному адресу памяти. Вам нужно создать вектор new и присвоить его v.

template <typename K, typename V> std::vector<bool>* HashTable<K,V>::wn_to_bool(long wn)
{
    auto v = new std::vector<bool>();

    for(;wn!=0;wm/=2)
        v->push_back(wn % 2 != 0);

    return v; 
}

. Вам не понадобится оператор if, поскольку вы непосредственно используете результат логического оператора. Вам просто нужно оттолкнуть wn%2 != 0, что намного эффективнее, чем if. Вы также можете использовать цикл for для большей читабельности, так как вы будете записывать всю логику в одну строку кода.

Как рекомендовано для комментариев, создание экземпляров объектов в динамической памяти (иначе говоря, с использованием new)следует использовать с достаточной осторожностью, потому что вам придется позаботиться об удалении выделенной памяти, когда она вам больше не понадобится, иначе это приведет к утечкам памяти. Вместо этого настоятельно рекомендуется использовать интеллектуальных указателей .

...