代码之家  ›  专栏  ›  技术社区  ›  Daniel Sloof

std::string::assign()导致segfault

  •  6
  • Daniel Sloof  · 技术社区  · 16 年前

    我有一个 std::vector<uint8_t> 它包含特定偏移量的字符串。这里有一个简短的转储文件:

    ...
    @128    00 00 00 00 00 00 00 00 73 6F 6D 65 74 68 69 33 ........somethin
    @144    38 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ng..............
    @160    00 00 00 00 00 00 00 00 31 2E 32 2E 33 00 00 00 ........1.2.3...
    @176    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    ...
    

    我试图提取偏移量136处的数据,并将其放入 std::string :

    std::string x;
    x.assign(vec.begin()+136, vec.begin()+168);
    

    但是,这会导致我的应用程序出错。现在我对Linux下的软件开发非常熟悉,但我知道如何在gdb中启动我的应用程序并获取回溯,并在这里跟踪问题:

    (gdb) backtrace
    #0  0xb7536d78 in ?? () from /lib/i686/cmov/libc.so.6
    #1  0xb7538cd5 in malloc () from /lib/i686/cmov/libc.so.6
    #2  0xb7708957 in operator new(unsigned int) () from /usr/lib/libstdc++.so.6
    #3  0xb76e4146 in std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) () from /usr/lib/libstdc++.so.6
    #4  0xb76e63b0 in std::string::_M_mutate(unsigned int, unsigned int, unsigned int) () from /usr/lib/libstdc++.so.6
    #5  0xb76e654a in std::string::_M_replace_safe(unsigned int, unsigned int, char const*, unsigned int) () from /usr/lib/libstdc++.so.6
    #6  0x0806d651 in std::string::_M_replace_dispatch<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > > (this=0xbfffe464, __i1=..., __i2=..., __k1=..., __k2=...) at /usr/include/c++/4.3/bits/basic_string.tcc:637
    #7  0x0806d26e in std::string::replace<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > > (this=0x811c730, vec=...) at /usr/include/c++/4.3/bits/basic_string.h:1390
    #8  std::string::assign<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > > (
        this=0x811c730, vec=...) at /usr/include/c++/4.3/bits/basic_string.h:958
    #9  myclass::somemethod (this=0x811c730, vec=...) at myclass.cpp:135
    

    印刷 vec.size() 返回200,甚至在向量上循环并打印数据都不会导致任何问题(正好在崩溃片段的上方!).

    我用G++4.3.4在Debian中编译。关于这个问题可能是什么有什么建议吗?

    1 回复  |  直到 13 年前
        1
  •  13
  •   Community Mohan Dere    8 年前

    代码中的其他地方可能存在不匹配的free/delete,从而将症状延迟到现在。当您使用释放的内存时,只要操作系统认为合适,它就可以自由地继续运行。

    尝试在Valgrind中运行程序。Valgrind使用它自己的malloc和free,这样它可以提醒你错误的新闻和删除。确保 compile without optimisations -g :

    g++ -g main.cc -o binary
    valgrind --leak-check=full ./binary
    

    确保不要从超出范围的堆栈变量创建指针。例如,这是新开发人员的常见错误:

    int *foo() {
        int a = 0;
        // do something to a here
        return &a;
    }
    

    当a超出范围时,您将返回一个指向释放内存的指针。


    关于 -G ,从手册页: 以操作系统的本机格式(stabs、coff、xcoff或dwarf 2)生成调试信息。gdb可以使用此调试信息。

    推荐文章