Если у меня есть следующий код:
{
UnicodeString sFish = L"FISH";
char *szFish = AnsiString(sFish).c_str();
CallFunc(szFish);
}
Тогда какова область действия временной созданной строки AnsiString и как долго szFish указывает на действительные данные? Будет ли он по-прежнему действителен для функции CallFunc?
Будет ли область видимости длиться всего одну строку или весь блок?
Стандарт C ++ 11 $ 12.2.3 гласит:
Когда реализация вводит временный объект класса, который
имеет нетривиальный конструктор (12.1, 12.8), он должен гарантировать, что
конструктор вызывается для временного объекта. Точно так же
деструктор должен быть вызван для временного с нетривиальным
деструктор (12.4). Временные объекты уничтожаются как последний шаг в
оценивая полное выражение (1.9), которое (лексически) содержит
Точка, где они были созданы. Это правда, даже если эта оценка
заканчивается броском исключения. Расчет стоимости и побочные эффекты
уничтожения временного объекта связаны только с
полное выражение, без какого-либо конкретного подвыражения.
(акцент мой)
Есть дополнительные предостережения по этому поводу, но они не применяются в этой ситуации. В вашем случае полное выражение является указанной частью этого утверждения:
char *szFish = AnsiString(sFish).c_str();
// ^^^^^^^^^^^^^^^^^^^^^^^^^
Итак, момент szFish
назначен, деструктор вашего временного объекта (т.е. AnsiString(sFish)
) будет вызываться и представление его внутренней памяти (где c_str()
указывает на) будет выпущен. Таким образом, szFish
будет немедленно становиться висящим указателем, и любой доступ потерпит неудачу.
Вы можете обойти это, сказав
CallFunc(AnsiString(sFish).c_str());
вместо этого, как здесь, временный будет уничтожен (снова) после полный выражение (то есть, прямо на ;
) а также CallFunc
сможет прочитать необработанную строку.
szFish
недействителен перед звонком CallFunc()
, так как AnsiString
это временный объект, который разрушается немедленно и szFish
указывает на свой внутренний буфер, который будет только что удален.
Убедитесь, что AnsiString
Экземпляр действителен для вызова CallFunc()
, Например:
CallFunc(AnsiString(sFish).c_str());
Я бы заменил:
char *szFish = AnsiString(sFish).c_str();
с:
AnsiString as(sFish);
char *szFish = as.c_str();
Я не знаю AnsiString
класс, но в вашем коде его деструктор сработает до вашего вызова CallFunc()
и, скорее всего, выпустит строку, на которую вы указываете *szFish
, Когда вы заменяете временный объект на «именованный» объект в стеке, его время жизни увеличивается до конца блока, в котором он определен.
Область действия AnsiString в этом случае — «прямо перед вызовом c_str () и сразу после». Это может помочь думать об этом так:
char *szFish;
{
AnsiString tmpString(sFish);
szFish = tmpString.c_str();
}