Error taking address of temporary array

Ошибка: taking address of temporary array C++ Решение и ответ на вопрос 2113788

amd-hoja

2 / 2 / 4

Регистрация: 24.03.2016

Сообщений: 75

1

31.10.2017, 16:35. Показов 2107. Ответов 5

Метки нет (Все метки)


снова при переходе с С на С++ вылазит ошибка с которой никак не разберусь

C
1
2
            dss->flag=ParseFlags(xcur, ptr, 0, &error, (char *[]) {"FORWARD", "FORWARD_CHG", NULL},
                                  (int [])  {DS_IPX_FLAG_FORWARD_ALL,DS_IPX_FLAG_FORWARD_CHG,0});

на С собирается все ОК.

на С++ на второй строчке

C
1
2
3
ошибка: taking address of temporary array
                                   (int [])  {DS_IPX_FLAG_FORWARD_ALL,DS_IPX_FLAG_FORWARD_CHG,0});
                                                                                                                                                    ^

судя по всему С++ не очень дружит с временными массивами и переменными.

как обойти эту ошибку.

компилятор GCC

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Mirmik

techpriest

634 / 213 / 57

Регистрация: 27.02.2014

Сообщений: 1,180

31.10.2017, 16:59

2

Например:

C++
1
2
3
const char* carr[] = {"FORWARD", "FORWARD_CHG", NULL};
int iarr[] =  {DS_IPX_FLAG_FORWARD_ALL,DS_IPX_FLAG_FORWARD_CHG,0};
dss->flag=ParseFlags(xcur, ptr, 0, &error, carr, iarr);



0



amd-hoja

2 / 2 / 4

Регистрация: 24.03.2016

Сообщений: 75

31.10.2017, 17:19

 [ТС]

3

пробовал подобное. все равно ошибка вылазит на iarr та же самая

C
1
2
3
ошибка: taking address of temporary array
                                   iarr);
                                       ^

кстати самое интересное что на (char *[]) ошибки нет. только на int



0



techpriest

634 / 213 / 57

Регистрация: 27.02.2014

Сообщений: 1,180

31.10.2017, 17:30

4

Хм… А что вообще такое ParseFlag? какая сигнатура?



0



TheCalligrapher

Вездепух

Эксперт CЭксперт С++

10435 / 5704 / 1553

Регистрация: 18.10.2014

Сообщений: 14,101

31.10.2017, 17:34

5

Цитата
Сообщение от amd-hoja
Посмотреть сообщение

на С++ вылазит ошибка с которой никак не разберусь

В С++ вообще нет таких конструкций, как

C
1
2
(char *[]) {"FORWARD", "FORWARD_CHG", NULL}
(int [])  {DS_IPX_FLAG_FORWARD_ALL,DS_IPX_FLAG_FORWARD_CHG,0}

Это исключительно С.

Цитата
Сообщение от amd-hoja
Посмотреть сообщение

кстати самое интересное что на (char *[]) ошибки нет.

Простой эксперимент показывает, что ошибка вылезает именно на (char *[]). Более того, GCC также будет ругаться на приведение строкового литерала к char *. В С++ нужен const char *. Да и в C не мешало бы использовать именно const char *.

Во-первых, приводите все диагностические сообщения. Во-вторых, почему до сих пор не приведено объявление ParseFlags? Телепатов тут нет.



1



amd-hoja

2 / 2 / 4

Регистрация: 24.03.2016

Сообщений: 75

01.11.2017, 09:29

 [ТС]

6

Цитата
Сообщение от TheCalligrapher
Посмотреть сообщение

Во-вторых, почему до сих пор не приведено объявление ParseFlags? Телепатов тут нет.

в .h

C++
1
extern int ParseFlags(xmlNodePtr cur, char *flags, int opt, int *error, char *fl_names[],int fl_vals[]);

в .cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
int ParseFlags(xmlNodePtr cur, char *flags, int opt, int *error, char *fl_names[],int fl_vals[])
{
    int n,v=0;
    int i, len; 
    char *ptr, *ptr2, str[MAXBUFLEN];
    ptr=flags;
    do
    {
        ptr2=GetNextAttrVal(ptr,&len);
        if (len)
        {
            n=0;
            strncpy(str,ptr,len); str[len]=0;
            for (i=0; fl_names[i]; i++)
            {
                if (!strcasecmp(str,fl_names[i])) { n=fl_vals[i]; break; }
            }
            if (!fl_names[i])
            {
                char *ptr3;
                n=GetNum(str,&ptr3);
                if (n && opt&FL_FLAG_NOT_NUM) *error=XmlErrorSet(xpc, cur, U_COMMON, XML_EM_FL_NUMVAL);
                if (ptr3==str) *error=XmlErrorSet(xpc, cur, U_COMMON, XML_EM_FL_NAN);
            }
            if (v && opt&FL_FLAG_ONE_VAL) *error=XmlErrorSet(xpc, cur, U_COMMON, XML_EM_FL_ONEVAL);
            v|=n;
        }
        ptr=ptr2;
    } while (ptr && !(*error));
    return v;
}

Добавлено через 4 минуты
все разобрался. действительно ругался именно на char* а не на int

прошел вариант с объявлением массивов заранее. я заменял только инт потому и не срабатывало.
только const пришлось убрать. ругался))

C++
1
2
3
char* carr[] = {"FORWARD", "FORWARD_CHG", NULL};
int iarr[] =  {DS_IPX_FLAG_FORWARD_ALL,DS_IPX_FLAG_FORWARD_CHG,0};
dss->flag=ParseFlags(xcur, ptr, 0, &error, carr, iarr);

спасибо



0



av_err2str makes use of C array constructs that break newer versions of G++.

See: https://ffmpeg.org/pipermail/libav-user/2013-January/003458.html

Error:

In file included from normalize_ts.cpp:37:0:
normalize_ts.cpp:217:49: error: taking address of temporary array
         fprintf(stderr, "Error occurred: %sn", av_err2str(ret));
                                                 ^
Makefile:725: recipe for target 'normalize_ts-normalize_ts.o' failed
make[2]: *** [normalize_ts-normalize_ts.o] Error 1
make[2]: Leaving directory '/home/ctxz/dev/composite-video-simulator'
Makefile:745: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/ctxz/dev/composite-video-simulator'
Makefile:448: recipe for target 'all' failed
make: *** [all] Error 2

G++:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.2.0-8ubuntu3.2' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3.2)

To work this issue around, I’ve placed the following macros, as suggested by this mail from the Libav-user mailinglist, after line line 40:

#undef av_err2str
#define av_err2str(errnum) av_make_error_string((char*)__builtin_alloca(AV_ERROR_MAX_STRING_SIZE), AV_ERROR_MAX_STRING_SIZE, errnum)

With av_err2str being overwritten, compilation succeeds.

Автор Тема: taking address of temporary  (Прочитано 11230 раз)
Mirael Karamir

Гость


Привет всем!
Столкнулся с такой проблемкой — при компилировании программы, компилятор постоянно выдает сообщение

warning: taking address of temporary

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


Записан
QCasper

Гость


Это значит, что ты пытаешься использовать адрес временной переменной, и это чревато access violation’ом. Если хочешь избавиться от варнинга, покажи кусок кода, где ты его получаешь. Всю эту функцию желательно, может кто-нить поможет. Хотя Qt здесь не причем. Оффтоп.


Записан
pastor

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

Сообщений: 2901

Просмотр профиля
WWW


Покажи строку, в которой возникает этот ворнинг. ИМХО, ты сохраняешь адресс временного объекта. Типа что-то такого:

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(…);


Записан

Mirael Karamir

Гость


Строка такая, в которой выдается warning такая
  doc=new QDomDocument(«test»);
  doc=&update->getData();

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


Записан
pastor

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

Сообщений: 2901

Просмотр профиля
WWW


Ворнинг очевидно в этой строке:

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

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 нужно будет удалить ручками


Записан

Mirael Karamir

Гость


Ворнинг очевидно в этой строке:

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

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 нужно будет удалить ручками

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


Записан
Racheengel

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

Сообщений: 2679

Я работал с дискетам 5.25 :(

Просмотр профиля


если это классы порожденные от QObject — то Qt сама удаляет их при удалении parent’a.


Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт

serg_hd

Хакер
*****
Offline Offline

Сообщений: 668

Просмотр профиля


Оно конечно всё это хорошо. У себя я тоже напоролся на это же дело, и исправил по совету. Но на вопрос почему объект временный (в моём случае 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»));


Записан

kubuntu/Win7/x64/NetBeans

lit-uriy


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

а вот это (выделенное) зачем?


Записан

Юра.

serg_hd

Хакер
*****
Offline Offline

Сообщений: 668

Просмотр профиля


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

а вот это (выделенное) зачем?

потому что this->browsersList — указатель
п.с. если бы я не исправил — предупреждение бы было, но программа всё равно работала бы как надо, т.е. доступ к QList’у по указателю всё равно был.

« Последнее редактирование: Апрель 06, 2010, 16:29 от serg_hd »
Записан

kubuntu/Win7/x64/NetBeans

niXman

Гость


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

покажите точное сообщение компилятора.


Записан
Alex Custov


Но на вопрос почему объект временный (в моём случае QList) дан не был. Ведь он объявлен как поле класса, а не внутри функции/метода, почему компилятор думает что он временный, и зачем же делать копию?

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

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


Записан
serg_hd

Хакер
*****
Offline Offline

Сообщений: 668

Просмотр профиля


понял, вопрос снят.
niXman, сообщение как тема топика + указание номера строки


Записан

kubuntu/Win7/x64/NetBeans

Igors


Дополню. При работе с контейнерами всегда нехорошо брать/хранить адрес элемента. Для QMap надо хранить ключ, для QVector — индекс и.т.п. Вот популярные грабли

QVector <int> vec;
vec.push_back(value);
int * valPtr = &vec[0];

vec.push_back(something);  // valPtr может стать invalid, непредсказуемо


Записан

Независимо от того, что я делаю, я всегда получаю одно и то же сообщение об ошибке. Может быть, у кого-то есть идея, что я могу изменить.

Это мой сценарий:

    void SendInventoryCustom(Player* player, Creature* vendor, int guid)
{
std::vector<ItemList> vendors = GetVendorList();
ItemList myVendor;
for(int i = 0; i < vendors.size(); i++)
{
if(vendors[i].GetVendor().getGuid() == guid)
{
myVendor = ItemList(&vendors[i].GetVendor(), &vendors[i].GetVendor().items);
break;
}
}

SmsgListInventory inventory_packet(vendor->GetGUID(), player->GetSession(), &myVendor.GetVendor().items, vendors);
inventory_packet.Send(vendor, player);
}

Во время компиляции я получаю следующее сообщение об ошибке:

1266:59: error: taking address of temporary [-fpermissive]

Строка 1266 начинается с:

myVendor = ItemList(&vendors[i].GetVendor(), &vendors[i].GetVendor().items);

И это полный сценарий:
http://pastebin.com/DNnyjEeT

Я был бы очень признателен, если бы кто-то мог помочь мне с моей проблемой.
Заранее спасибо, С наилучшими пожеланиями!

5

Решение

В коде сниппер

&vendors[i].GetVendor()

Применение оператора address-of к объекту, не имеющему значения, не является обязательным в соответствии со стандартом. Некоторые компиляторы могут разрешить это с предупреждениями или переопределением компилятора, но помните, что он некорректен и его следует избегать.

Назначьте возвращаемое значение вызова функции для объекта, локального / нелокального lvalue а затем взять адрес объекта.

Стандарт цитирования

§5.3.1 Унарные операторы, раздел 3

Результат одинарный & Оператор является указателем на свой операнд.
операнд должен быть lvalue или квалифицированным идентификатором.

4

Другие решения

Когда вы сталкиваетесь с предупреждением, вы должны понимать каждый термин (который может потребовать некоторых исследований).

В C ++ временным является безымянный объект, который появляется при вычислении выражения, например:

int a = 5 + 3 * 6;

Эквивалентно:

int a = operator+(5, operator*(3, 6));

Результат operator*(3, 6) временный тип intЭто означает, что компилятор переписывает код в нечто вроде:

int __1 = 3 * 6;
int a = 5 + __1;

Это может случиться во многих ситуациях, например:

int foo();

int a = 5 + foo(); // converted to `int __foo = foo(); int a = 5 + __foo;`

Итак, теперь перейдем к предупреждению, в чем проблема с принимая адрес временного ?

Проблема в том, что язык только гарантирует, что временные доживут до конца полного выражения (в основном, до ;). Поэтому, взяв его адрес (или создав ссылку на него), вы получаете свисающий указательуказатель, который указывает на пустоту.

Таким образом, вы можете формально взять адрес, но вы никогда не должны пытаться получить доступ к его значению впоследствии …

Прагматически, компилятору разрешено (и gcc ввел его в 4.7) для повторного использования памяти, занятой временными объектами, из одного выражения в другое, поскольку они никогда не сосуществуют. Если вы используете ранее «захваченный» адрес для временного, вы можете случайно перезаписать другой объект!

Рассматривать:

void foo(int* a, int b) { std::cout << (*a + b) << "n"; }

int* i = &(5 + 3);
foo(i, 7 + 6);

Это Можно быть переведены на:

int __1 = 5 + 3;
int* i = &__1;

__1 = 7 + 6;
foo(i, __1); // equivalent to `foo(&__1, __1);`

6

Понравилась статья? Поделить с друзьями:
  • Error tags must be specified as a list
  • Error tag asset filename in the container scenery is obsolete
  • Error tadtextureconvert trainzutil command host terminated unexpectedly
  • Error tables declared with oids are not supported
  • Error t shirt