Russian Qt Forum

Qt => Общие вопросы => Тема начата: Mira от Ноябрь 09, 2015, 08:03



Название: Программа падает при изменении строки.
Отправлено: 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, но под виндой тоже надо заставить работать.
Буду рада любым советам!


Название: Re: Программа падает при изменении строки.
Отправлено: ssoft от Ноябрь 09, 2015, 08:24
Сразу напрашивается вопрос - strInfoList.at(0) существует? Т.е. размер списка strInfoList больше нуля.
Чтобы не проверять можно использовать strInfoList.value(0).

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

Операционка ни при чем.


Название: Re: Программа падает при изменении строки.
Отправлено: Old от Ноябрь 09, 2015, 08:28
пока качаю linux, но под виндой тоже надо заставить работать.
Как скачаете linux, запустите вашу программу под valgrind, он вам покажет места где вы бьете память. Частенько место падения никак не связано с местом порчи памяти. :)



Название: Re: Программа падает при изменении строки.
Отправлено: Mira от Ноябрь 09, 2015, 08:30
существование  strInfoList было проверенно в первую очередь (и сейчас перед ответом перепроверенно).

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

если это поможет - прога падала на месте передачи строки в функцию до установки const. Теперь в функцию стал передавать стабильно - падает в ней.


Название: Re: Программа падает при изменении строки.
Отправлено: Mira от Ноябрь 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  зарегистрирован собственно в этом классе как элемент вектора.


Название: Re: Программа падает при изменении строки.
Отправлено: Old от Ноябрь 09, 2015, 08:35
используется memset для выделения памяти под pDataModel (для котороой вызывается функция).
Так стоп, не надо выделять память через memset, она так не выделяется, а заполняется указанным значением. :)
Убирайте memset, выделяйте память через new и присваивайте начальные значения только для полей int, строка и так будет сконструирована пустой.


Название: Re: Программа падает при изменении строки.
Отправлено: Mira от Ноябрь 09, 2015, 08:40

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

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



Название: Re: Программа падает при изменении строки.
Отправлено: Old от Ноябрь 09, 2015, 08:45
Покажите где и как создаются объекты класса UpdaterUpdateData.


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

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


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


Название: Re: Программа падает при изменении строки.
Отправлено: Mira от Ноябрь 09, 2015, 10:32
Класс не мой, я не могу его править не имея соответствующей задачи, доказывать старшему программисту что у него в классе небезопасное место тоже желания нет %)

Я вообще мемсет никогда не использую - не приперает. Но теперь буду знать где тонкое место.