Какова область этой строки?
Если у меня есть следующий код:
{
UnicodeString sFish = L"FISH";
char *szFish = AnsiString(sFish).c_str();
CallFunc(szFish);
}
Тогда какова область действия временной созданной строки AnsiString и как долго szFish указывает на действительные данные? Будет ли он по-прежнему действителен для функции CallFunc?
Будет ли область видимости длиться всего одну строку или весь блок?
4 ответа
Стандарт 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();
}