2010-04-29 3 views
7

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

Но когда я делаю 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*/ 
}; 

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

Seg fault after is item pushed onto STL container

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

Существует один такой, который беспокоит меня как ад! Когда я сначала вставляю некоторые данные в вектор, все идет хорошо. Позже в коде, когда я пытаюсь вставить еще несколько данных в вектор, мое приложение просто 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 3.4.5 mingw без проблем ...

help!

--- ... ---

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

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

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); 
+1

Показать код, который выталкивает его, пожалуйста. –

+1

Ваша структура dos не нуждается в конструкторе копирования, и это плохая идея предоставить его - конструктор копирования по умолчанию делает все, что вам нужно. Вы также не нуждаетесь в typedef в структуре.Он также не нуждается в деструкторе и, вероятно, не в конструкторе, который принимает размер. – 2010-04-29 17:22:14

+0

@Neil. Я знаю! Я добавил их из «отчаяния» –

ответ

0

Хорошо ...

valgrind на помощь! То, что вызвало меня в журнале valgrind, было этой штукой.

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 и < Groups.size() [предпочтительное решение].

Так что пригодился Джону и Джошу за то, что он напомнил мне о вальгринде.

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

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

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

Приветствия

1

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

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

6

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

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

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

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

1

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

Смежные вопросы