Вопрос

If I have the following code:

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

    CallFunc(szFish);
}

Then what is the scope of the temporary AnsiString that's created, and for how long is szFish pointing to valid data? Will it still be valid for the CallFunc function?

Will it's scope last just the one line, or for the whole block?

Это было полезно?

Решение 3

The C++11 standard $12.2.3 says:

When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1, 12.8), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (12.4). Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception. The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.

(emphasis mine)

There are additional caveats to this, but they don't apply in this situation. In your case the full expression is the indicated part of this statement:

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

So, the instant szFish is assigned, the destructor of your temporary object (i.e. AnsiString(sFish)) will be called and its internal memory representation (where c_str() points to) will be released. Thus, szFish will be immediately become a dangling pointer and any access will fail.

You can get around this by saying

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

instead, as here, the temporary will be destroyed (again) after the full expression (that is, right at the ;) and CallFunc will be able to read the raw string.

Другие советы

szFish is invalid before the call to CallFunc(), because AnsiString is a temporary object that is destructed immediately and szFish is pointing to its internal buffer which will have just been deleted.

Ensure that the AnsiString instance is valid for the invocation of CallFunc(). For example:

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

I would replace:

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

with:

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

I don't know the AnsiString class but in your code its destructor will fire before your call to CallFunc(), and will most probably release the string you point to with *szFish. When you replace the temporary object with a "named" object on stack its lifetime will extend until the end of the block it is defined in.

The scope of the AnsiString in this case is "from right before the call to c_str(), until right after."

It may help to think of it this way:

char *szFish; 

{ 
    AnsiString tmpString(sFish); 
    szFish = tmpString.c_str(); 
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top