сегмент по вектору <struct> - PullRequest
7 голосов
/ 29 апреля 2010

Я создал структуру для хранения некоторых данных, а затем объявил вектор для этой структуры.

Но когда я делаю push_back, я получаю чертово segfault, и я понятия не имею, почему!

Моя структура определяется как:

typedef struct Group
{
    int codigo;
    string name;
    int deleted;
    int printers;
    int subpage;

    /*included this when it started segfaulting*/
    Group(){ name.reserve(MAX_PRODUCT_LONG_NAME); }
    ~Group(){ name.clear(); }
    Group(const Group &b)
    {
    codigo = b.codigo;
    name = b.name;
    deleted = b.deleted;
    printers = b.printers;
    subpage = b.subpage;
    }
   /*end of new stuff*/
 };

Изначально структура не имела копии, конструктора или деструктора. Я добавил их позже, когда прочитал этот пост ниже.

Ошибка сегмента после того, как элемент помещен в контейнер STL

но конечный результат тот же.

Есть одна такая, которая чертовски беспокоит меня! Когда я впервые помещаю некоторые данные в вектор, все идет хорошо. Позже в коде, когда я пытаюсь вставить еще какие-то данные в вектор, мое приложение просто segfaults!

Вектор объявлен

vector<Group> Groups

и является глобальной переменной для файла, в котором я ее использую. Больше нигде нет и т.д ...

Я могу отследить ошибку до:

_M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage- this->_M_impl._M_start);

в vector.tcc, когда я заканчиваю добавлять / копировать последний элемент в вектор ....

Насколько я могу судить. Мне не нужно ничего делать с конструктором копирования, так как для этого должно быть достаточно мелкой копии. Я даже не выделяю места (но я сделал резерв для строки, чтобы попробовать).

Понятия не имею, в чем проблема!

я запускаю этот код в OpenSuse 10.2 с gcc 4.1.2

Мне не очень хочется обновлять gcc из-за проблем с обратной совместимостью ...

Этот код работал "отлично" на моей машине с Windows. Я скомпилировал его с gcc 3.4.5 mingw без проблем ...

помощь!

--- ... ---

::: РЕДАКТИРОВАТЬ :::

я нажимаю данные

Group tmp_grp;

(...)

tmp_grp.name = "Nova ";
tmp_grp.codigo=GetGroupnextcode();
tmp_grp.deleted=0;
tmp_grp.printers=0;
tmp_grp.subpage=0;
Groups.push_back(tmp_grp);

Ответы [ 4 ]

6 голосов
/ 29 апреля 2010

Как сказал Нил, вам не нужен конструктор по умолчанию, конструктор копирования или деструктор:

  • std::string убирает за собой, поэтому ваш деструктор не нужен.
  • Компилятор, предоставленный компилятором, будет работать нормально.
  • std::string::reserve не требуется, поскольку std::string будет динамически распределять память по мере необходимости, но может обеспечивать выигрыш в производительности.

Код, который вы опубликовали, выглядит правильно (и выглядит очень просто и понятно, поэтому трудно понять, где может появиться ошибка). Поэтому я подозреваю, что вы повреждаете память в другом месте своего кода и что vector<Group> является просто жертвой.

Попробуйте установить Valgrind (OpenSuse должен предоставить пакет для него) и запустить ваше приложение через него (из командной строки, просто запустите valgrind my-app), чтобы увидеть, может ли Valgrind уловить любое повреждение памяти.

1 голос
/ 29 апреля 2010

Ошибки памяти, подобные этой, могут быть вызваны удалением одной и той же памяти дважды или удалением памяти, которую вы не получили из новой. Ошибки часто происходят намного позже, чем в таких местах, как это. Как уже говорилось в DeadMG, установите valgrind и найдите другие, казалось бы, не связанные с памятью проблемы.

1 голос
/ 29 апреля 2010

Вы обязательно должны удалить деструктор. C ++ будет автоматически вызывать деструктор для всех элементов данных, и выполнение действий с элементами, у которых уже есть такой деструктор, не нужно и может быть небезопасно.

Но я не вижу ничего плохого в вашем коде как таковом. Вам придется опубликовать немного больше об этом. Попробуйте расширить раздел (...) - покажите нам весь код, который включает вектор.

0 голосов
/ 30 апреля 2010

Ну ...

Вэлгринд на помощь! В журнале Вальгринда меня вызвал этот кусок.

Invalid write of size 4
==4639==    at 0x805BDC0: ChangeGroups() (articles.cpp:405)
==4639==    by 0x80AC008: GeneralConfigChange() (config.cpp:4474)
==4639==    by 0x80EE28C: teste() (main.cpp:2259)
==4639==    by 0x80EEBB3: main (main.cpp:2516)

В этот момент в файле я делал это

Groups[oldselected].subpage=SL.selected_code();

а что если oldselected находилось за пределами вектора?

В этом случае все, что происходило, было то, что oldselected могло быть -1 ... и хотя это не было сбоем в этот момент, оно писало что-то в другом месте ...

Мне, вероятно, следует начать использовать оператор at () и проверить наличие исключения или просто проверить, является ли "oldselected"> 0 и

Итак, спасибо Джону и Джошу за напоминание о Вальгринде.

Я использовал его раньше, но никогда не нуждался в том, чтобы сделать что-то существенное с этим (к счастью: D).

Интересно, что в окнах я не вижу этого ошибки. Проблема была та же ... Я думаю, что это как-то связано с управлением памятью и компилятором ... это действительно ускользает от меня.

Спасибо всем за вклад;)

Приветствия

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...