Russian Qt Forum

Qt => Общие вопросы => Тема начата: Mirael Karamir от Май 22, 2007, 17:29



Название: taking address of temporary
Отправлено: Mirael Karamir от Май 22, 2007, 17:29
Привет всем!
Столкнулся с такой проблемкой - при компилировании программы, компилятор постоянно выдает сообщение

warning: taking address of temporary

Сама программа собирается и работает без проблем,  мне просто интересно знать, что этот warning значит, почему возникает, и стоит ли на него обращать внимание.
Спасибо за помощь :)


Название: taking address of temporary
Отправлено: QCasper от Май 22, 2007, 18:48
Это значит, что ты пытаешься использовать адрес временной переменной, и это чревато access violation'ом. Если хочешь избавиться от варнинга, покажи кусок кода, где ты его получаешь. Всю эту функцию желательно, может кто-нить поможет. Хотя Qt здесь не причем. Оффтоп.


Название: Re: taking address of temporary
Отправлено: pastor от Май 22, 2007, 18:52
Покажи строку, в которой возникает этот ворнинг. ИМХО, ты сохраняешь адресс временного объекта. Типа что-то такого:

Код:
Foo* array_of_foo[3];

array_of_foo[0] = &Foo(...);
array_of_foo[1] = &Foo(...);
...


В таком случае нужно применять new:

Код:
Foo* array_of_foo[3];

array_of_foo[0] =  new Foo(...);
array_of_foo[1] = new Foo(...);
...


Название: taking address of temporary
Отправлено: Mirael Karamir от Май 23, 2007, 10:39
Строка такая, в которой выдается warning такая
  doc=new QDomDocument("test");
  doc=&update->getData();

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


Название: taking address of temporary
Отправлено: pastor от Май 23, 2007, 12:46
Ворнинг очевидно в этой строке:
Код:

doc=&update->getData();


Можно сделать например так:
Код:

QDomDocument doc(update->getData()); - шаровая копия.
QDomDocument doc(update->getData().cloneNode(true)); - не шаровая копия

Тоже самое можно сделать динамически:
Код:

QDomDocument *doc = new QDomDocument(update->getData()); - шаровая копия.
QDomDocument *doc = new QDomDocument(update->getData().cloneNode(true)); - не шаровая копия


В этом случае doc нужно будет удалить ручками


Название: taking address of temporary
Отправлено: Mirael Karamir от Май 23, 2007, 16:35
Цитата: "pastor"
Ворнинг очевидно в этой строке:
Код:

doc=&update->getData();


Можно сделать например так:
Код:

QDomDocument doc(update->getData()); - шаровая копия.
QDomDocument doc(update->getData().cloneNode(true)); - не шаровая копия

Тоже самое можно сделать динамически:
Код:

QDomDocument *doc = new QDomDocument(update->getData()); - шаровая копия.
QDomDocument *doc = new QDomDocument(update->getData().cloneNode(true)); - не шаровая копия


В этом случае doc нужно будет удалить ручками


Большое спасибо, это помогло! К слову, еще один вопрос - обязательно ли нужно вручную удалять динамически созданные переменные? У меня в программе большинство членов класса создаются именно таким образом.


Название: taking address of temporary
Отправлено: Racheengel от Май 23, 2007, 19:32
если это классы порожденные от QObject - то Qt сама удаляет их при удалении parent'a.


Название: Re: taking address of temporary
Отправлено: serg_hd от Апрель 06, 2010, 16:18
Оно конечно всё это хорошо. У себя я тоже напоролся на это же дело, и исправил по совету. Но на вопрос почему объект временный (в моём случае QList) дан не был. Ведь он объявлен как поле класса, а не внутри функции/метода, почему компилятор думает что он временный, и зачем же делать копию?
Код:
поля класса:
 QList<QMap<QString, QString> > list;
 QMap<QString, QList<QMap<QString, QString> > > browsers;
 const QList<QMap<QString, QString> >* browsersList;
 
в конструкторе:
 QMap<QString, QString> map;
 map.insert("strstr", "strstr");
 this->list.append(map);
 this->browsers.insert("browsers", this->list);
 this->browsersList = &this->browsers.value("browsers"); //ошибка временного объекта
 

исправил: this->browsersList = new QList<QMap<QString, QString> >(this->browsers.value("browsers"));


Название: Re: taking address of temporary
Отправлено: lit-uriy от Апрель 06, 2010, 16:23
Цитировать
this->browsersList = &this->browsers.value("browsers"); //ошибка временного объекта
а вот это (выделенное) зачем?


Название: Re: taking address of temporary
Отправлено: serg_hd от Апрель 06, 2010, 16:27
Цитировать
this->browsersList = &this->browsers.value("browsers"); //ошибка временного объекта
а вот это (выделенное) зачем?
потому что this->browsersList - указатель
п.с. если бы я не исправил - предупреждение бы было, но программа всё равно работала бы как надо, т.е. доступ к QList'у по указателю всё равно был.


Название: Re: taking address of temporary
Отправлено: niXman от Апрель 06, 2010, 16:52
Цитировать
this->browsersList = &this->browsers.value("browsers"); //ошибка временного объекта
покажите точное сообщение компилятора.


Название: Re: taking address of temporary
Отправлено: Alex Custov от Апрель 06, 2010, 16:59
Но на вопрос почему объект временный (в моём случае QList) дан не был. Ведь он объявлен как поле класса, а не внутри функции/метода, почему компилятор думает что он временный, и зачем же делать копию?

Код:
this->browsersList = &this->browsers.value("browsers"); //ошибка временного объекта

Естественно, ты берёшь адрес объекта из стека (QMap::value()). При выходе из контекста вызова это значение удалится и адрес станет невалидным. Это же не QMap::operator[], который возвращает ссылку.


Название: Re: taking address of temporary
Отправлено: serg_hd от Апрель 06, 2010, 17:07
понял, вопрос снят.
niXman, сообщение как тема топика + указание номера строки


Название: Re: taking address of temporary
Отправлено: Igors от Апрель 07, 2010, 04:59
Дополню. При работе с контейнерами всегда нехорошо брать/хранить адрес элемента. Для QMap надо хранить ключ, для QVector - индекс и.т.п. Вот популярные грабли

Код:
QVector <int> vec;
vec.push_back(value);
int * valPtr = &vec[0];
...
vec.push_back(something);  // valPtr может стать invalid, непредсказуемо