Я создал структуру для содержания некоторых данных и затем объявил, что вектор содержал ту структуру.
Но когда я делаю 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 после является объектом, продвинутым на контейнер STL
но конечным результатом является то же.
Существует один это, которое беспокоит меня как ад! Когда я сначала продвигаю некоторые данные в вектор, все идет прекрасное. Позже в коде, когда я пытаюсь продвинуть еще некоторые данные в вектор, мое приложение просто segfaults!
Вектор объявляется
vector 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 из-за проблем обратной совместимости...
Этот код работал "отлично" над моей машиной окон. Я скомпилировал его с 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);
Ну ...
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 и Так что слава Джону и Джошу за то, что они напомнили мне вальгринд. Я использовал его раньше, но мне никогда не приходилось делать с ним ничего существенного (к счастью: D). Интересно, что в windows я не получаю этого segfault. Проблема была та же ... Я предполагаю, что это как-то связано с управлением памятью и компилятором ... это действительно ускользает от меня. Спасибо всем за вклад;) Ура
Подобные ошибки памяти могут быть вызваны двойным удалением одной и той же памяти или удалением памяти, которую вы не получили из новой. В подобных местах ошибки часто возникают спустя долгое время после их возникновения. Как уже говорилось в DeadMG, установите valgrind и найдите другие, казалось бы, не связанные проблемы с памятью.
Как сказал Нил, вам не нужен конструктор по умолчанию, конструктор копирования или деструктор:
std::string
убирает за собой, поэтому деструктор никогда не нужен. std::string::reserve
не нужен, поскольку std::string
будет динамически выделять память по мере необходимости, но он может обеспечить выигрыш в производительности. Код, который вы опубликовали, выглядит корректным (и он выглядит очень простым и понятным, поэтому трудно понять, где может закрасться ошибка). Поэтому я подозреваю, что вы повреждаете память в другом месте вашего кода, а vector
просто является жертвой.
Попробуйте установить Valgrind (OpenSuse должен предоставить пакет для него) и запустить ваше приложение через него (из командной строки просто выполните valgrind my-app
), чтобы посмотреть, сможет ли Valgrind обнаружить повреждение памяти.
Вы обязательно должны удалить деструктор. C ++ автоматически вызывает деструктор всех членов данных, и выполнение действий с членами, у которых уже есть такой деструктор, не нужно и может быть небезопасно.
Но я не вижу ничего плохого в вашем коде как таковом. Вам придется опубликовать еще немного. Попробуйте расширить раздел (...) - покажите нам весь код, связанный с вектором.