将 std::to_string(x).c_str() 存储在成员变量中会产生垃圾 [英] Storing std::to_string(x).c_str() in member variable produces garbage
问题描述
我有一个非常简单的 C++ 程序:
I have this very simple C++ program:
using namespace std;
class TheClass
{
private:
const char *_numberString;
public:
TheClass(int number)
{
_numberString = to_string(number).c_str();
}
operator const char *()
{
return _numberString;
}
};
int main(int argc, const char * argv[])
{
TheClass instance = 123;
cout << (const char *)instance << endl;
return 0;
}
当我在 Xcode 中运行它时,它会记录 \367\277_\377
.但是,如果我将其更改为:
When I run it in Xcode, it logs \367\277_\377
. If I change it to this however:
using namespace std;
class TheClass
{
public: // Change 1/2
const char *_numberString;
public:
TheClass(int number)
{
_numberString = to_string(number).c_str();
}
operator const char *()
{
return _numberString;
}
};
int main(int argc, const char * argv[])
{
TheClass instance = 123;
instance._numberString = to_string(123).c_str(); // Change 2/2
cout << (const char *)instance << endl;
return 0;
}
它像它应该的那样记录123
.我看不出我做错了什么.即使我将 123 更改为另一个数字,也会记录完全相同的内容.
it logs 123
like it should. I can't see what I'm doing wrong. Even if I change 123 to another number the exact same thing is logged.
推荐答案
此时
_numberString = to_string(number).c_str();
您正在存储一个指向临时 std::string
值的内部数据的指针,该值在该行代码之后无效.
you are storing a pointer to the interned data of a temporary std::string
value, that is invalidated after that line of code.
访问 _numberString
有效调用未定义的行为.
Accessing _numberString
effectively calls undefined behavior.
正如评论中提到的,将 _numberString
1 成员保留为 const char*
是没有意义的.改用 std::string
成员:
As mentioned in comments, there's no point to keep the _numberString
1 member as const char*
. Use a std::string
member instead:
class TheClass {
private:
std::string numberString_;
public:
TheClass(int number) : numberString_(to_string(number)) {
}
operator const std::string& () {
return numberString_;
}
};
<小时>
1) 你不应该使用前缀 _
作为类成员名称,这是为编译器和标准实现内部函数保留的.如果你不喜欢像 m_
这样的模式或其他前缀约定(像我一样),只需使用后缀 _
如我的示例所示.
1) You shouldn't use prefixed _
for class member names, that's reserved for compiler and standard implementation intrinsics. If you dislike patterns like m_
or other prefix conventions (like me), just use a postfix _
as shown in my sample.
这篇关于将 std::to_string(x).c_str() 存储在成员变量中会产生垃圾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!