7

我有一个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 中编译。关于这个问题可能是什么的任何指示?

4

1 回答 1

14

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

尝试在 valgrind 中运行程序。valgrind 使用自己的 malloc 和 free,因此它可以提醒您注意不正确的新闻和删除。确保在没有优化的情况下使用1进行编译-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 超出范围,您将返回一个指向已释放内存的指针。


1关于-g,来自联机帮助页:以操作系统的本机格式(stabs、COFF、XCOFF 或 DWARF 2)生成调试信息。GDB 可以使用这些调试信息。

于 2009-09-14T00:20:14.690 回答