What's the scope of this string?

拈花ヽ惹草 提交于 2019-12-19 10:12:38

问题


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?


回答1:


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.




回答2:


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());



回答3:


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.




回答4:


The scope of 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(); 
}


来源:https://stackoverflow.com/questions/13474486/whats-the-scope-of-this-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!