0

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

I was expecting program to output Text_5, instead it outputs:

╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ɽ÷Y╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠⌠ ╠╠╠╠╠╠╠╠

krsi
  • 1,045
  • 2
  • 14
  • 24
  • ╠ is 0xCC in codepage 437, and [MSVC fills 0xCC to uninitialized memory to help debugging](https://stackoverflow.com/q/370195/995714). That means you've accessed uninitialized memory. You can find tons of questions about ╠ and 0xCC here on SO – phuclv Aug 18 '18 at 10:57

1 Answers1

3

Don't do this. Don't attempt to store the result of std::string::c_str().

Sub-expression

"Text_" + std::to_string(5)

produces a temporary std::string object, which is immediately automatically destroyed after the execution of the full expression

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

When that object is destroyed, C-string "Text_5" pointed by c_str()'s result is destroyed as well. So, your m_var pointer ends up pointing to nowhere. What you see printed is garbage from that "nowhere". The behavior is formally undefined.

For example, this will work "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.

But this won't

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;

And this will work "as expected" again

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;

But in any case, don't try to use the result of c_str() for long-term storage. And if you are dealing with temporary objects, don't even think about storing it at all. It is intended to be used only for a moment, preferably within a single expression. If you store the pointer returned by c_str(), you risk suddenly discovering that it became invalid without you noticing. Formally it is possible to keep that pointer for a while as long as you really know what you are doing. But what you have above is a schoolbook example of when it fails.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765