std :: unordered_map выдает ошибку сегмента при вставке определенного ключа - PullRequest
0 голосов
/ 24 октября 2018

У меня есть база кода Python, которая иногда вызывает программы на C ++ для обработки интенсивных рабочих нагрузок.Один такой код должен подсчитать всех кмеров определенного размера в большом текстовом файле.Для каждой строки, которую он читает, создается временный индекс, в котором хранится позиция каждого кмера.Вот функция, которая обрабатывает каждую строку:

void process_read(char* read, int num) {
    int l = strlen(read) ;
    std::string seq(read) ;
    // index kmers
    std::unordered_map<std::string, std::vector<int>> index ;
    for (int i = 0 ; i <= l - 1 - 15 ; i++) {
        std::string k = seq.substr(i, 15) ;
        if (global_index->find(k) == global_index->end()) {
            continue ;
        }
        if (index.find(k) == index.end()) {
            index.insert(std::make_pair(k, std::vector<int>(1, i))) ;
        } else {
            index[k].push_back(i) ;
        }
    }
    // 50+ lines of code commented out. It returns here
}

Код падает каждый раз, когда достигает определенной строки ввода:

ACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCAAACCATAACCCTAAACCTCACGATAACCCAAACCATCACCAAAAAAAAAAAAAACACACCTACCGAAACCAACAACATA

Только из kmers в этой строке AAAAAAAAAAAAAAC и CAAAAAAAAAAAAAA делают это для индексации.Код всегда вылетает при попытке вставить CAAAAAAAAAAAAAA по какой-то причине, которую я не понимаю.Я думаю, проблема в том, что эти ключи вставляются в unordered_map по порядку.Изменение этой функции по-прежнему приведет к тому же сбою при вставке второй клавиши:

void process_read(char* read, int num) {
    std::unordered_map<std::string, std::vector<int>> index ;
    index.insert(std::make_pair("AAAAAAAAAAAAAAC", std::vector<int>(1, 2))) ;
    index.insert(std::make_pair("CAAAAAAAAAAAAAA", std::vector<int>(1, 2))) ;
}

Теперь эта функция явно не имеет доступа ни к какому глобальному состоянию в отличие от исходного, поэтому проблема должна быть с этими конкретнымиключи (обратите внимание, что один является круговым сдвигом другого, используемая хеш-функция может быть неудобна с этим);тем не менее, размещение этого кода в начале программы или написание другой небольшой программы, которая только и делает это, похоже, не воспроизводит сбой, поэтому я в замешательстве.

Любое предложение приветствуется.

Обновление: я получаю эту трассировку стека во время сбоя.По причинам, я не могу использовать GDB для отладки, поэтому я думаю, что это лучшее, что я собираюсь получить.Но не знаю, как это интерпретировать.

*** Error in `src/python/kmer/c_counter.out': malloc(): memory corruption (fast): 0x0000000001eac690 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f189daa47e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x82651)[0x7f189daaf651]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x54)[0x7f189dab1184]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_Znwm+0x18)[0x7f189e3a3e78]
/src/python/kmer/c_counter.out[0x41c5e4]
/src/python/kmer/c_counter.out[0x4146ea]
/src/python/kmer/c_counter.out[0x41453a]
/src/python/kmer/c_counter.out[0x41035b]
/src/python/kmer/c_counter.out[0x40b3d8]
/src/python/kmer/c_counter.out[0x40940a]
/src/python/kmer/c_counter.out[0x404528]
/src/python/kmer/c_counter.out[0x404f9d]
/src/python/kmer/c_counter.out[0x405f42]
/src/python/kmer/c_counter.out[0x4063d6]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f189da4d830]
/src/python/kmer/c_counter.out[0x403b39]
======= Memory map: ========
00400000-00440000 r-xp 00000000 00:2f 546796                             src/python/kmer/c_counter.out
0063f000-00640000 rw-p 0003f000 00:2f 546796                             src/python/kmer/c_counter.out
014a0000-01ebf000 rw-p 00000000 00:00 0                                  [heap]
7f1898000000-7f1898021000 rw-p 00000000 00:00 0
7f1898021000-7f189c000000 ---p 00000000 00:00 0
7f189da2d000-7f189dbed000 r-xp 00000000 fc:00 1439150                    /lib/x86_64-linux-gnu/libc-2.23.so
7f189dbed000-7f189dded000 ---p 001c0000 fc:00 1439150                    /lib/x86_64-linux-gnu/libc-2.23.so
7f189dded000-7f189ddf1000 r--p 001c0000 fc:00 1439150                    /lib/x86_64-linux-gnu/libc-2.23.so
7f189ddf1000-7f189ddf3000 rw-p 001c4000 fc:00 1439150                    /lib/x86_64-linux-gnu/libc-2.23.so
7f189ddf3000-7f189ddf7000 rw-p 00000000 00:00 0
7f189ddf7000-7f189de0d000 r-xp 00000000 fc:00 1439041                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f189de0d000-7f189e00c000 ---p 00016000 fc:00 1439041                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f189e00c000-7f189e00d000 rw-p 00015000 fc:00 1439041                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f189e00d000-7f189e115000 r-xp 00000000 fc:00 1439141                    /lib/x86_64-linux-gnu/libm-2.23.so
7f189e115000-7f189e314000 ---p 00108000 fc:00 1439141                    /lib/x86_64-linux-gnu/libm-2.23.so
7f189e314000-7f189e315000 r--p 00107000 fc:00 1439141                    /lib/x86_64-linux-gnu/libm-2.23.so
7f189e315000-7f189e316000 rw-p 00108000 fc:00 1439141                    /lib/x86_64-linux-gnu/libm-2.23.so
7f189e316000-7f189e488000 r-xp 00000000 fc:00 671990                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f189e488000-7f189e688000 ---p 00172000 fc:00 671990                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f189e688000-7f189e692000 r--p 00172000 fc:00 671990                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f189e692000-7f189e694000 rw-p 0017c000 fc:00 671990                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f189e694000-7f189e698000 rw-p 00000000 00:00 0
7f189e698000-7f189e6be000 r-xp 00000000 fc:00 1439146                    /lib/x86_64-linux-gnu/ld-2.23.so
7f189e878000-7f189e89f000 rw-p 00000000 00:00 0
7f189e8bc000-7f189e8bd000 rw-p 00000000 00:00 0
7f189e8bd000-7f189e8be000 r--p 00025000 fc:00 1439146                    /lib/x86_64-linux-gnu/ld-2.23.so
7f189e8be000-7f189e8bf000 rw-p 00026000 fc:00 1439146                    /lib/x86_64-linux-gnu/ld-2.23.so
7f189e8bf000-7f189e8c0000 rw-p 00000000 00:00 0
7ffea4907000-7ffea4929000 rw-p 00000000 00:00 0                          [stack]
7ffea49b6000-7ffea49b9000 r--p 00000000 00:00 0                          [vvar]
7ffea49b9000-7ffea49bb000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Изменение этой функции по-прежнему приведет к той же аварии при вставке второй клавиши:

[...]

, помещающей этот код в начало программыили написание другой маленькой программы, которая только этого не делает, похоже, не воспроизводит сбой, поэтому я в замешательстве.Я запускаю эту тестовую функцию при запуске "и", если я запускаю эту тестовую функцию позже, карта вылетает ".У вас есть повреждение памяти из-за неопределенного поведения где-то еще в вашей программе - сделанные вами наблюдения являются самым сильным доказательством, которое вы можете получить для этого.

0 голосов
/ 24 октября 2018

Сигнатура функции предполагает, что у вас не обязательно должна быть строка с нулевым окончанием (та, которая имеет \ 0 в качестве последнего символа).

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

Если бы я был тобой, я бы собрал двоичный файл с помощью Valgrind или другого инструмента анализа памяти и снова запустил его.Он обнаружит неправильный доступ там, где это происходит.

То, как вы используете unordered_map, мне подходит.

...