Russian Qt Forum

Qt => Общие вопросы => Тема начата: aliks-os от Январь 13, 2011, 15:14



Название: Глюк QList или моя ошибка
Отправлено: aliks-os от Январь 13, 2011, 15:14
Есть структура

Код:
struct ConData {
    QString name;
    QString driver;
    QString dbName;
    QString host;
    QString user;
    QString password;
    int port;
    QString charset;
    int charsetIdx;
};

Загнал ее в массив

Код:
QList<ConData> connectionList;

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

Код:
ConnectionDlg *dialog = new ConnectionDlg(this);
ConData co1 = connectionList.at(curCon);  //curCon - это номер строки в массиве
ConData co = dialog->showThis(co1);

Далее, пытаюсь полученное значение подменить в массиве. И вот тут проблемы...
если делаю вот так...

Код:
connectionList.replace(curCon,co);

то программа потом вылетает, трассировка из-за чего не помогает.
А если делаю вот так, то все ок

Код:
connectionList[curCon].host = co.host;
...
и так все поля.

Подскажите, где моя ошибка и как это побороть


Название: Re: Глюк QList или моя ошибка
Отправлено: Fat-Zer от Январь 13, 2011, 15:34
вроде ничего криминального не видно...
Цитировать
Код:
connectionList.replace(curCon,co);

то программа потом вылетает, трассировка из-за чего не помогает.
странно что не помогает, хотя бы побольше информации о том как валится... сигфолт? тогда коллстек посмотрите, где именно.

Цитировать
Код:
connectionList[curCon].host = co.host;
...
и так все поля.

Подскажите, где моя ошибка и как это побороть
почему не просто
Код:
connectionList[curCon]=co;


Название: Re: Глюк QList или моя ошибка
Отправлено: aliks-os от Январь 13, 2011, 15:48
Если напишу просто
Код:
connectionList[curCon]=co;

то у меня тоже возникает ошибка при повторном обращении....При дебуге, ошибка возникает в
файле qatomic_i386.h
а конкретно в функции

Код:
inline bool QBasicAtomicInt::ref()
{
    unsigned char ret;
    asm volatile("lock\n"
                 "incl %0\n"
                 "setne %1"
                 : "=m" (_q_value), "=qm" (ret)
                 : "m" (_q_value)
                 : "memory");
    return ret != 0;
}


Ошибка возникает как не странное при обращении к QTreeWidget, хотя они у меня ни как не связаны


Название: Re: Глюк QList или моя ошибка
Отправлено: Fat-Zer от Январь 13, 2011, 16:21
Цитировать
хотя бы побольше информации о том как валится

в том коде, который вы привели явных ошибок нет.


Название: Re: Глюк QList или моя ошибка
Отправлено: Igors от Январь 13, 2011, 16:51
Наиболее вероятно - битая куча. Кто-то пишет по удаленному указателю или др. невалидному адресу. В результате калечится объект(ы) который не имеет к пишущему никакого отношения. Нужно запрягать отладчик на предмет проверки кучи, хотя это не всегда помогат. Простой способ - воткнуть строку (connectionList[curCon]=co;) "до и после" и так пытаться локализоваться


Название: Re: Глюк QList или моя ошибка
Отправлено: aliks-os от Январь 13, 2011, 17:14
ну то что куча битая, я это понял. уже победил, вот таким способом.

Код:
ConData *co1 = &(connectionList[curCon]);
ConData co = *dialog->showThis(co1);
connectionList[curCon] = co;

Стал передавать в функцию указатель и она его же возвращает


Название: Re: Глюк QList или моя ошибка
Отправлено: Igors от Январь 13, 2011, 17:37
ну то что куча битая, я это понял. уже победил, вот таким способом.

Код:
ConData *co1 = &(connectionList[curCon]);
ConData co = *dialog->showThis(co1);
connectionList[curCon] = co;

Стал передавать в функцию указатель и она его же возвращает
Ну это Вы заткнули "до следующего милиционера". Нужно найти кто бьет и устранить. И на всякий случай поставить проверку curCon < connectionList.size()


Название: Re: Глюк QList или моя ошибка
Отправлено: aliks-os от Январь 13, 2011, 17:52
Ну это Вы заткнули "до следующего милиционера". Нужно найти кто бьет и устранить. И на всякий случай поставить проверку curCon < connectionList.size()

Согласен, буду искать еще, проверку curCon < connectionList.size() сделаю обязательно, но в данном случае ошибка была не из-за него


Название: Re: Глюк QList или моя ошибка
Отправлено: Авварон от Январь 13, 2011, 17:59
я бы конструктор копирования написал, класс-то не POD


Название: Re: Глюк QList или моя ошибка
Отправлено: aliks-os от Январь 13, 2011, 18:11
а подробней можно?


Название: Re: Глюк QList или моя ошибка
Отправлено: Пантер от Январь 13, 2011, 19:32
Копирующий конструктор типа:
ConData (const ConData& cd) : name (cd.name), и т.д. {
 
}


Название: Re: Глюк QList или моя ошибка
Отправлено: Fat-Zer от Январь 13, 2011, 20:12
я бы конструктор копирования написал, класс-то не POD
А в этом есть смысл? тобишь ведь он ни чем не будет отличаться от того, что по умолчанию...


Название: Re: Глюк QList или моя ошибка
Отправлено: Авварон от Январь 13, 2011, 20:19
ну вообще-то будет, по умолчанию происходит что-то типа memcpy насколько я знаю, а конструкторы кустрингов вроде не вызовуться


Название: Re: Глюк QList или моя ошибка
Отправлено: Fat-Zer от Январь 13, 2011, 21:01
ну вообще-то будет, по умолчанию происходит что-то типа memcpy насколько я знаю, а конструкторы кустрингов вроде не вызовуться
я до недавнего времени тоже так считал, но меня образумили))
1) конструктор копирования по умолчанию вызывает оные для всех членов.
2) в данном случае будет вызываться не конструктор копирования, а оператор присваивания.

пример:
Код
C++ (Qt)
#include <iostream>
 
using namespace std;
 
struct SubStruct
{
public:
SubStruct()
{
cout<<"in substruct constructor\n";
}
SubStruct(const SubStruct&)
{
cout<<"in substruct copy constructor\n";
}
const SubStruct& operator=(const SubStruct&)
{
cout<<"in substruct operator=\n";
return *this;
}
};
 
 
struct MyStruct
{
public:
SubStruct ss;
};
 
 
int main(int , char *[])
{
cout<<"Creation:\n";
MyStruct s1, s2;
cout<<"Assigning:\n";
s2=s1;
cout<<"Copyconstructing=)\n";
MyStruct s3(s1);
 
return 0;
}
 


Название: Re: Глюк QList или моя ошибка
Отправлено: Пантер от Январь 13, 2011, 21:27
Ну, вообще советуют:
1. Если переопределяешь конструктор копирования, то и присваивание тоже переопределяй.
2. Конструктор копирования реализуется через присваивание.


Название: Re: Глюк QList или моя ошибка
Отправлено: brankovic от Январь 13, 2011, 23:57
Есть структура...

А на винде дело-то? А то на линуксах тупо valgrind запустил, часто сразу понятно, что не так..


Название: Re: Глюк QList или моя ошибка
Отправлено: ритт от Январь 15, 2011, 19:32
ну вообще-то будет, по умолчанию происходит что-то типа memcpy насколько я знаю, а конструкторы кустрингов вроде не вызовуться
мета-тип не примитив и не мувэйбл - memcpy происходить не будет.


Название: Re: Глюк QList или моя ошибка
Отправлено: lit-uriy от Январь 15, 2011, 21:05
2) в данном случае будет вызываться не конструктор копирования, а оператор присваивания.
тут нужно быть по осторожнее т.к. теория может расходится с практикой (оптимизация компилятора)
Тыц (http://www.forum.crossplatform.ru/index.php?showtopic=5123)


Название: Re: Глюк QList или моя ошибка
Отправлено: Igors от Январь 15, 2011, 23:48
2) в данном случае будет вызываться не конструктор копирования, а оператор присваивания.
тут нужно быть по осторожнее т.к. теория может расходится с практикой (оптимизация компилятора)
Тыц (http://www.forum.crossplatform.ru/index.php?showtopic=5123)
Как пояснил Rcus - это стандартная оптимизация практически для всех современных компиляторов.
Код
C++ (Qt)
MyObject CreateObj( void )   // наглое возвращение объекта по значению
{
MyObject obj;
return obj;
}
...
MyObject theObj = CreateObj();
 
Здесь компилятор не позовет деструктор для локального obj, итого будет вызван всего 1 конструктор MyObj. Однако никакая оптимизация не заменяет конструирование на присваивание или наоборот, напр
Код
C++ (Qt)
theObj = CreateObj();  // theObj был объявлен выше
 
А вот здесь как ни оптимизируй, а будет вызван оператор присваивания и деструктор
Кстати интересно проверить (для первого случая) - а что будет если конструктор копирования и по умолчанию чем-то различаются?

Edit; наверное правильнее сказать: в первом случае локальный obj вообще не создается, а сразу используется "место назначения" (theObj)


Название: Re: Глюк QList или моя ошибка
Отправлено: brankovic от Январь 16, 2011, 00:34
Edit; наверное правильнее сказать: в первом случае локальный obj вообще не создается, а сразу используется "место назначения" (theObj)

Именно. Только это не "какая-то оптимизиция некоторых компиляторов", это разрешено и поощряется стандартом, называется copy constructor elision. Даже если конструктор копирования и конструктор по умолчанию различаются, компилятор имеет право бездумно сократить, опять в соответствии со стандартом. Гарантий нет. Вплоть до того, что на разном уровне оптимизации будет работать по-разному.


Название: Re: Глюк QList или моя ошибка
Отправлено: Igors от Январь 16, 2011, 01:07
Именно. Только это не "какая-то оптимизиция некоторых компиляторов",
Я такого не говорил, наоборот  :)

Даже если конструктор копирования и конструктор по умолчанию различаются, компилятор имеет право бездумно сократить, опять в соответствии со стандартом. Гарантий нет. Вплоть до того, что на разном уровне оптимизации будет работать по-разному.
Хммм... интересно разобраться. Представим ситуацию когда:

- конструктор по умолчанию заводит новый shared объект (указатель на него - член класса)
- конструктор копирования только увеличивает число ссылок на него (как и оператор присваивания)

И что - это будет работать по-разному?
Хотя я бы лично по значению объектов бы не возвращал (ну разве что-то типа QPoint, QRect)