Temporary whose address is used as value of local variable 'pr' will be destroyed at the end of the full-expression (C++)?
А в чем тут ошибка? Возникла после обновления на версию движка 5.2. Локальная переменная pr будет уничтожена после завершения выражения.
Ответы (2 шт):
Насколько я понял TCHAR_TO_UTF8 это специальный макрос который освободит выделенную под строку память сразу после ";" поэтому указатель pr окажется висящим. Ошибка возникла вероятнее всего потому что с новой версией добавили больше проверок на подобные ошибки в коде. Использование макросов непосредственно в выражении где используются указатели должно решить проблему.
Макрос TCHAR_TO_UTF8 создаёт внутри себя объект типа FTCHARToUTF8 и возвращает указатель на внутреннюю память этого объекта:
#define TCHAR_TO_UTF8(str) (ANSICHAR*)FTCHARToUTF8((const TCHAR*)str).Get()
Время жизни анонимного объекта типа FTCHARToUTF8 до конца statement-а. Соответственно, в строке 595 вашего кода этот объект уже не существует, и указатель pr указывает в память с неопределённым содержимым.
Если не использовать временную переменную pr, то ошибка должна исчезнуть:
const chat * getItem = element->Attribute(TCHAR_TO_UTF8(*attrName));
В этом случае временный объект будет существовать до завершения вызова функции, и временный указатель, возвращенный методом Get, будет валиден.
Вот пример висящей ссылки:
#include <iostream>
using namespace std;
class A {
private:
int x;
public:
A(int x) : x(x) {
cout << "A(" << x << ")" << endl;
}
~A() {
cout << "~A(" << x << ")" << endl;
}
int* get() { return &x; }
};
class B {
private:
int* ptr;
public:
B(int* ptr) : ptr(ptr) {
cout << "B(&" << *ptr << ")" << endl;
}
~B() {
cout << "~B(&" << *ptr << ")" << endl;
}
int* get() { return ptr; }
int operator * () { return *ptr; }
};
#define Z(x) (A((x)).get())
int main() {
{
int x = 42;
cout << "Before Z" << endl;
B y = Z(x);
cout << "After Z" << endl;
cout << "*y = " << *y << endl;
}
cout << "The end!";
return 0;
}
Before Z
A(42)
B(&42)
~A(42)
After Z
*y = 42
~B(&42)
Внутри макроса Z создаётся объект типа A. Этот объект существует до конца инициализации B y, сразу после инициазации уничтожается. Поэтому y.ptr указывает на уже освобождённую память. В этом примере, вообще говоря, повезло, что память не испортилась.
Если main немного подкрутить, добавив дополнительные переменные, то содержимое y необратимо портится:
int main() {
{
int x = 42;
cout << "Before Z" << endl;
B y = Z(x);
cout << "After Z" << endl;
int zero = 0;
B b_zero = &zero;
cout << "*y = " << *y << endl;
cout << "*b_zero = " << *b_zero << endl;
}
cout << "The end!";
return 0;
}
Before Z
A(42)
B(&42)
~A(42)
After Z
B(&0)
*y = -341712064
*b_zero = 0
~B(&0)
~B(&-341712064)


