c++ - std::unordered_map 插入特定键时抛出 seg 错误

标签 c++ unordered-map

我有一个 python 代码库,有时会调用 C++ 程序来处理密集型工作负载。这样的代码必须计算大型文本文件中特定大小的所有公里数。对于它读取的每一行,它都会创建一个临时索引来存储每个 kmer 的位置。这是处理每一行的函数:

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 中,只有 AAAAAAAAAAAAAACCAAAAAAAAAAAAA 进入索引。由于某种我不明白的原因,尝试插入 CAAAAAAAAAAAAAAA 时,代码总是崩溃。我猜想这些键按顺序插入到 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]

最佳答案

Changing the function to this will still result in the same crash when inserting the second key:

[...]

putting this code at the start of the program or writing another small program that only does this doesn't seem to reproduce the crash so I'm really confused.

std::unordered_map 没有相关的全局状态,可以在“如果我在开始时运行此测试函数,一切都很好”和“如果我稍后运行此测试函数, map 崩溃”之间发生变化”。由于程序中其他地方的未定义行为,您出现了内存损坏 - 您所做的观察是您可以获得的最有力的证据。

关于c++ - std::unordered_map 插入特定键时抛出 seg 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52962797/

相关文章:

c++ - OpenGl 2d 缩放(使用缩放和平移而不是 glOrtho)

不同类型的 C++ 映射赋值重载

unordered_map 中 operator[] 的 C++ 特化

c++ - 使用对象中的方法调用带有 std::bind 和 std::function.target 的 C 风格函数地址

c++ - 使用 WinAPI 附加禁用的显示设备

c++ - g++ 不能在 Mac OS X Mavericks 上编译

c++ - std::unordered_map 相等性是否取决于插入顺序

c++ - 访问 unordered_maps 作为指针

c++ - 使用 unordered_map 移动构造函数

c++ - 为什么存在奇特的指针?