字符指针未按预期初始化

时间:2017-10-31 06:11:50

标签: c++ pointers initializer-list 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╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠⌠

1 个答案:

答案 0 :(得分:3)

不要这样做。请勿尝试存储 std::string::c_str()的结果。

子表达式

"Text_" + std::to_string(5)

生成临时 std::string对象,在执行完整表达式后立即自动销毁

("Text_" + std::to_string(5)).c_str()

当该对象被销毁时,"Text_5"的结果所指向的C字符串c_str()也会被销毁。所以,你的m_var指针最终指向无处。你看到的印刷品是那些&#34;无处不在的垃圾。该行为正式未定义。

例如,这将按预期工作&#34;

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;

这将起作用&#34;正如所料&#34;再次

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()返回的指针,您可能会突然发现它在没有您注意到的情况下变为无效。只要你真的知道自己在做什么,形式上就可以将指针保留一段时间。但你上面所说的是教科书失败时的例子。