ОШИБКА СЕГМЕНТАЦИИ в функции итератора vector‹string›, используемой для рисования текста в моем графическом интерфейсе с самокодированием

Приветствую всех,

ОШИБКА: программа получила сигнал "SIGSEGV", ошибка сегментации.

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

Строка, создающая ошибку: [if(iter->empty());]. Если я удалю эту строку, она все равно вызовет ошибку при вызове функции DrawText.

Может кто-нибудь мне помочь? В данный момент для меня это был кошмар, пытаясь отладить его!

FYI -> Я кодирую в Code:: Blocks на Ubuntu. Программа использует SDL, особенно заголовки net и thread. Функция DrawText — это просто оболочка для TTF_RenderTextBlended() и SDL_BlitSurface, но я знаю, что ошибка не в функции DrawText, потому что я использовал ее во многих других проектах без каких-либо проблем.

Все, что я проверяю, указывает на наличие проблемы со строками в векторе, но я не могу понять, что именно?

void GUI_ChatBox::Render(SDL_Surface *screen)
{
  int line = 0;
  for(vector<string>::reverse_iterator iter = L.rbegin(); iter != L.rend(); ++iter)
  {
    if(iter->empty())
        continue;

    ++line;
    DrawText(screen, iter->c_str(), x, (y + height) - (line * CHAR_HEIGHT));
  }
}

L в приведенном выше примере был сокращением от LineBuffer. Только одна другая функция взаимодействует с ним, и это функция, используемая для добавления текста в вектор. Вот:

void GUI_ChatBox::AddText(std::string text)
{
    ++index;
    if(index >= maxLines)
    {
        index = maxLines;
        LineBuffer.erase(LineBuffer.begin());
    }

    LineBuffer.push_back(text);
}

Эта функция обычно получает массив char* в качестве параметра std::string, но я сделал это в другом месте без проблем.


person sethXM    schedule 03.08.2010    source источник
comment
Вы, вероятно, делаете что-то странное в другом месте. Запустите свой код с помощью инструмента valgrind, вы, вероятно, увидите, где.   -  person nos    schedule 03.08.2010


Ответы (3)


Где определяется L? И как он инициализируется? Изменяет ли его какой-либо другой код после инициализации намеренно или случайно? Похоже, вектор по какой-то причине содержит мусор. Проблема почти наверняка не в коде, который вы здесь представили, а скорее в каком-то другом коде, который взаимодействует с L. Возможно, у вас есть переполненный массив где-то еще, который, например, затирает L.

person Peter Milley    schedule 03.08.2010
comment
Следующий вопрос: Render и AddText вызываются из отдельных потоков? Это могло бы легко объяснить это. Вызов LineBuffer.erase() в AddText сделает недействительными итераторы в Render. В противном случае мое следующее предположение будет заключаться в том, что какой-то другой код случайно перезаписывает память в LineBuffer. - person Peter Milley; 03.08.2010
comment
Та же нить. Я думаю, что я разобрался с причиной, сейчас я опубликую ее. - person sethXM; 03.08.2010

  1. Если 0 не является допустимым значением аргумента функции screen, то я настоятельно рекомендую использовать передачу по ссылке вместо передачи по указателю; даже сделайте его const, если DrawText, где он фактически используется, позволяет это.
  2. Вы говорите, что «строка, создающая ошибку, [if(iter->empty());]. Если я удалю эту строку, она все равно вызовет ошибку при вызове функции DrawText». Каков наименьший общий знаменатель этих двух строк? Да, iter->.
  3. Откуда iter? Да, L.
  4. Откуда L? Ну это только ты знаешь.
  5. Где-то между созданием L и его использованием в GUI_ChatBox::Render он попадает в корзину.
person Johann Gerell    schedule 03.08.2010

Я прошел весь свой код, наблюдая за тем, что было передано в функцию AddText, что могло бы сломать мой вектор LineBuffer.

Я нашел одну непонятную ссылку на функцию GetText для моего текстового поля, которая возвращает (char*) с символами в текстовом поле.

Эта функция вернет NULL, если в текстовом поле нет символов. Я прошел и изменил все, чтобы работать со строками, кроме внутренних объектов. А сейчас вроде все нормально играет. По крайней мере, я не могу воспроизвести указанную выше ошибку после внесения этих изменений.

Я подумал, что поставлю этот ответ на случай, если он поможет кому-то еще в такой же ситуации.

person sethXM    schedule 03.08.2010
comment
Нет, это не исправило. Похоже, он просто ушел на некоторое время, а теперь вернулся! - person sethXM; 03.08.2010