Какова область этой строки?

Если у меня есть следующий код:

{
UnicodeString sFish = L"FISH";
char *szFish = AnsiString(sFish).c_str();

CallFunc(szFish);
}

Тогда какова область действия временной созданной строки AnsiString и как долго szFish указывает на действительные данные? Будет ли он по-прежнему действителен для функции CallFunc?

Будет ли область видимости длиться всего одну строку или весь блок?

2

Решение

Стандарт 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 сможет прочитать необработанную строку.

2

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

szFish недействителен перед звонком CallFunc(), так как AnsiString это временный объект, который разрушается немедленно и szFish указывает на свой внутренний буфер, который будет только что удален.

Убедитесь, что AnsiString Экземпляр действителен для вызова CallFunc(), Например:

CallFunc(AnsiString(sFish).c_str());
5

Я бы заменил:

char *szFish = AnsiString(sFish).c_str();

с:

AnsiString as(sFish);
char *szFish = as.c_str();

Я не знаю AnsiString класс, но в вашем коде его деструктор сработает до вашего вызова CallFunc()и, скорее всего, выпустит строку, на которую вы указываете *szFish, Когда вы заменяете временный объект на «именованный» объект в стеке, его время жизни увеличивается до конца блока, в котором он определен.

4

Область действия AnsiString в этом случае — «прямо перед вызовом c_str () и сразу после». Это может помочь думать об этом так:

char *szFish;

{
AnsiString tmpString(sFish);
szFish = tmpString.c_str();
}
1
По вопросам рекламы [email protected]