Russian Qt Forum
Март 29, 2024, 17:09 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Программа падает при изменении строки.  (Прочитано 4686 раз)
Mira
Гость
« : Ноябрь 09, 2015, 08:03 »

Добрый день всем!
Прошу помочь в следующем вопросе - в простейшую функцию сеттер передается строка, внутри функции строка присваивается члену класса. Все! На этом месте прога падает, причем далеко не всегда (ну один из 5 Улыбающийся )

Код простой как три рубля:
Код:
struct updaterUpdateInfo {
QString strProductName;
QString strAbout;
QString strVersion;
QString strFileName;
int nFileSize;
int nFileId;
QString strSHA1;
QString strHttpLink;
};

class UpdaterUpdateData : public TModelItem<UpdaterUpdateData>{
public:
UpdaterUpdateData(){}
QString getProductName() { return m_updateData.strProductName; }
void setProductName(const QString & _strProductName) { m_updateData.strProductName = _strProductName; }

... //то же самое для остальных членов структуры

private:
updaterUpdateInfo m_updateData;
}

Вызываю просто:    
Код:
pDataModel->setProductName(strInfoList.at(0));

Сразу скажу пробовались варианты: вызывать метод со строкой в явном виде (строчкой ранее создавалась строка и ей присваивалось значение элемента списка), в самом классе вместо присваивания использовались clear и append -итог один.

Меня терзают смутные сомнения что что-то не так с моей операционкой, на Linuxe соседа не падало (ну конечно может 10 запусков было маловато).

пока качаю linux, но под виндой тоже надо заставить работать.
Буду рада любым советам!
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 574


Просмотр профиля
« Ответ #1 : Ноябрь 09, 2015, 08:24 »

Сразу напрашивается вопрос - strInfoList.at(0) существует? Т.е. размер списка strInfoList больше нуля.
Чтобы не проверять можно использовать strInfoList.value(0).

Второй возможный вариант - memcpy нигде не используется?

Операционка ни при чем.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #2 : Ноябрь 09, 2015, 08:28 »

пока качаю linux, но под виндой тоже надо заставить работать.
Как скачаете linux, запустите вашу программу под valgrind, он вам покажет места где вы бьете память. Частенько место падения никак не связано с местом порчи памяти. Улыбающийся

Записан
Mira
Гость
« Ответ #3 : Ноябрь 09, 2015, 08:30 »

существование  strInfoList было проверенно в первую очередь (и сейчас перед ответом перепроверенно).

memcpy не используется, используется memset для выделения памяти под pDataModel (для котороой вызывается функция).

если это поможет - прога падала на месте передачи строки в функцию до установки const. Теперь в функцию стал передавать стабильно - падает в ней.
Записан
Mira
Гость
« Ответ #4 : Ноябрь 09, 2015, 08:34 »

Ну тут стоит заметить что объект: в котором хранятся данные является членом хитропопого класса, который выдан мне в готовом виде.
И да, там есть memset.

Код:
class GlobalModel : public QObject {
Q_OBJECT

public:
GlobalModel() {
m_modelItems.resize(IModelItem::getModelItemsCount());
memset(&m_modelItems, 0, IModelItem::getModelItemsCount());
}

void registerModelItem(IModelItem * _pModelItem) {
m_modelItems[_pModelItem->getItemId()] = _pModelItem;
}

template<typename TItem> TItem * getModelItem() const {
return static_cast<TItem *>(m_modelItems[TItem::ms_itemId]);
}

private:
std::vector<IModelItem *> m_modelItems;
};


то есть pDataModel  зарегистрирован собственно в этом классе как элемент вектора.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #5 : Ноябрь 09, 2015, 08:35 »

используется memset для выделения памяти под pDataModel (для котороой вызывается функция).
Так стоп, не надо выделять память через memset, она так не выделяется, а заполняется указанным значением. Улыбающийся
Убирайте memset, выделяйте память через new и присваивайте начальные значения только для полей int, строка и так будет сконструирована пустой.
Записан
Mira
Гость
« Ответ #6 : Ноябрь 09, 2015, 08:40 »


используется memset для выделения памяти под pDataModel (для котороой вызывается функция).
Так стоп, не надо выделять память через memset, она так не выделяется, а заполняется указанным значением. Улыбающийся
Убирайте memset, выделяйте память через new и присваивайте начальные значения только для полей int, строка и так будет сконструирована пустой.
[/quote]

класс с memset ом не мой, смутно понимаю как он работает, и как вместо memseta и предыдущей строки выделения памяти (я так понимаю) туда вствить new?

Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #7 : Ноябрь 09, 2015, 08:45 »

Покажите где и как создаются объекты класса UpdaterUpdateData.
Записан
Mira
Гость
« Ответ #8 : Ноябрь 09, 2015, 09:14 »

Спасибо за помощь, вашими усилиями проблема была локализована, найден создатель хитрого класса и строчка memset поправленна на
      
Код:
memset(&m_modelItems[0], 0, IModelItem::getModelItemsCount()*sizeof(IModelItem *));

Вообще данный класс создает глобальную модель, регистрирующую в себе все другие модели разных классов, таким образом другие классы обмениваются данными просто меняя свойства глобальной модели.
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 574


Просмотр профиля
« Ответ #9 : Ноябрь 09, 2015, 10:07 »

Вы уверены, что такое использование memset безопасно? Надеюсь не забыли по необходимость явного удаления IModelItem через delete в таком массиве.
Почему бы не воспользоваться стандартными методами std::vector?
Записан
Mira
Гость
« Ответ #10 : Ноябрь 09, 2015, 10:32 »

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

Я вообще мемсет никогда не использую - не приперает. Но теперь буду знать где тонкое место.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.049 секунд. Запросов: 22.