此字符串的作用域是什么?

What's the scope of this string?

本文关键字:是什么 作用域 字符串      更新时间:2023-10-16

如果我有以下代码:

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

那么,创建的临时AnsiString的范围是什么?szFish指向有效数据的时间是多长?它对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指向的字符串。当你用堆栈上的"命名"对象替换临时对象时,它的生存期将延长,直到它在中定义的块结束

C++11标准12.2.3美元说:

当一个实现引入一个类的临时对象时有一个非平凡的构造函数(12.1,12.8),它应确保为临时对象调用构造函数。类似地析构函数应被调用为具有destructor(12.4)。临时对象在评估(词汇上)包含创建它们的点即使评估结果为最终引发异常。价值计算和副作用销毁临时对象的仅与完整表达式,不包含任何特定的子表达式。

(强调矿)

还有一些额外的注意事项,但它们不适用于这种情况。在你的情况下,完整的表达是这句话的指示部分:

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

因此,在分配szFish的瞬间,将调用临时对象(即AnsiString(sFish))的析构函数,并释放其内部内存表示(c_str()指向的位置)。因此,szFish将立即成为悬空指针,并且任何访问都将失败。

你可以通过说来解决这个问题

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

相反,与这里一样,临时将在完整表达式之后(即,就在;处)被销毁,并且CallFunc将能够读取原始字符串。

在这种情况下,AnsiString的作用域是"从调用c_str()之前一直到调用之后。">

这样想可能会有所帮助:

char *szFish; 
{ 
AnsiString tmpString(sFish); 
szFish = tmpString.c_str(); 
}