Вопрос

У меня есть 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);

Это, однако, вызывает мое приложение к segfault. Теперь я довольно новичок в разработке программного обеспечения под 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 и даже зацикливание на векторе, и печать данных не доставляет мне проблем (ровно над аварийным фрагментом!).

Я собираю в Debian с g ++ 4.3.4. Есть какие-нибудь указатели на то, что эта проблема может быть?

Это было полезно?

Решение

Скорее всего, в вашем коде есть несоответствующее освобождение / удаление, которое задерживает симптом до сих пор. Когда вы используете освобожденную память, операционная система может продолжать работу так долго, как считает нужным.

Попробуйте запустить программу в valgrind. valgrind использует свой собственный malloc и бесплатный, поэтому он может предупредить вас о неправильных новостях и удаляет. Обязательно компилируйте без оптимизации и с помощью -g 1 :

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

Убедитесь, что вы не создаете указатель из переменной стека, которая выходит из области видимости. Например, это распространенная ошибка среди новых разработчиков:

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

Как только вы вышли из области видимости, вы возвращаете указатель на освобожденную память.

<Ч>

1 О <=>, из man-страницы: Создать отладочную информацию в собственном формате операционной системы (stabs, COFF, XCOFF или DWARF 2). GDB может работать с этой отладочной информацией.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top