字符指针未按预期初始化
Char pointer doesn't initialize as expected
MyClass.h
#pragma once
class MyClass {
public:
const char* m_var;
MyClass();
};
MyClass.cpp
#include <iostream>
#include <sstream>
#include "MyClass.h"
MyClass::MyClass() :
m_var(("Text_" + std::to_string(5)).c_str())
{}
Main.cpp
#include <iostream>
#include "MyClass.h"
int main()
{
MyClass myClass;
std::cout << myClass.m_var;
std::cin.get();
}
我期待程序输出 Text_5
,但它输出:
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠ɽ÷Y╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠⌠╠╠╠╠╠╠╠╠
不要这样做。不要试图 存储 std::string::c_str()
.
的结果
子表达式
"Text_" + std::to_string(5)
产生一个临时std::string
对象,在完整表达式[=22]执行后立即自动销毁 =]
("Text_" + std::to_string(5)).c_str()
当该对象被销毁时,c_str()
的结果指向的 C 字符串 "Text_5"
也被销毁。因此,您的 m_var
指针最终指向任何地方。您看到的打印内容是来自 "nowhere" 的垃圾。该行为正式未定义。
例如,这会起作用 "as expected"
std::cout << ("Text_" + std::to_string(5)).c_str() << std::endl;
// The temporary is destroyed at the end of the full expression.
// It lives long enough to make the above output succeed.
但这不会
const char *str = ("Text_" + std::to_string(5)).c_str();
// The temporary is destroyed at the end of the above expression.
// Here it is already dead, meaning that `str` is an invalid pointer
// and the output below will not work
std::cout << str << std::endl;
这将再次起作用 "as expected"
std::string s = "Text_" + std::to_string(5);
const char *str = s.c_str();
// Since `s` is not a temporary, it is not destroyed here, `str` remains
// valid and the output below works
std::cout << str << std::endl;
但无论如何,不要试图将c_str()
的结果用于长期存储。如果你正在处理临时对象,根本不要考虑存储它。它旨在仅用于片刻,最好在单个表达式中使用。如果您存储 c_str()
返回的指针,您可能会突然发现它在您不注意的情况下变得无效。形式上,只要您真正知道自己在做什么,就可以将该指针保留一段时间。但是你上面的是一个失败的教科书例子。
MyClass.h
#pragma once
class MyClass {
public:
const char* m_var;
MyClass();
};
MyClass.cpp
#include <iostream>
#include <sstream>
#include "MyClass.h"
MyClass::MyClass() :
m_var(("Text_" + std::to_string(5)).c_str())
{}
Main.cpp
#include <iostream>
#include "MyClass.h"
int main()
{
MyClass myClass;
std::cout << myClass.m_var;
std::cin.get();
}
我期待程序输出 Text_5
,但它输出:
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠ɽ÷Y╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠⌠╠╠╠╠╠╠╠╠
不要这样做。不要试图 存储 std::string::c_str()
.
子表达式
"Text_" + std::to_string(5)
产生一个临时std::string
对象,在完整表达式[=22]执行后立即自动销毁 =]
("Text_" + std::to_string(5)).c_str()
当该对象被销毁时,c_str()
的结果指向的 C 字符串 "Text_5"
也被销毁。因此,您的 m_var
指针最终指向任何地方。您看到的打印内容是来自 "nowhere" 的垃圾。该行为正式未定义。
例如,这会起作用 "as expected"
std::cout << ("Text_" + std::to_string(5)).c_str() << std::endl;
// The temporary is destroyed at the end of the full expression.
// It lives long enough to make the above output succeed.
但这不会
const char *str = ("Text_" + std::to_string(5)).c_str();
// The temporary is destroyed at the end of the above expression.
// Here it is already dead, meaning that `str` is an invalid pointer
// and the output below will not work
std::cout << str << std::endl;
这将再次起作用 "as expected"
std::string s = "Text_" + std::to_string(5);
const char *str = s.c_str();
// Since `s` is not a temporary, it is not destroyed here, `str` remains
// valid and the output below works
std::cout << str << std::endl;
但无论如何,不要试图将c_str()
的结果用于长期存储。如果你正在处理临时对象,根本不要考虑存储它。它旨在仅用于片刻,最好在单个表达式中使用。如果您存储 c_str()
返回的指针,您可能会突然发现它在您不注意的情况下变得无效。形式上,只要您真正知道自己在做什么,就可以将该指针保留一段时间。但是你上面的是一个失败的教科书例子。