1

I have a number that I need to convert to a const char * (an API I'm using them requires const char * as input to many of its functions). The following works:

int num = 5;
std::string s = std::to_string(5);
const char * p = s.c_str();

as suggested by answers like those in how to convert from int to char*?, but it involves creating the seemingly unnecessary variable s, so I tried the following, but it doesn't work (p points to an empty string afterwards):

int num = 5;
const char * p = std::to_string(num).c_str();

Is there a clean way I can accomplish this? Why doesn't the second example work? The behavior is very similar to what happens if I made this obvious mistake:

const char * p;
{
    std::string tempStr( "hi" );
    p = tempStr.c_str( );
    // p points to "hi" string.
}
// now p points to "" string.

Which makes me suspect that the issue std::to_string(num) immediately goes out of scope or something similar because it's not used to directly initialize anything.

curiousguy
  • 8,038
  • 2
  • 40
  • 58
aquirdturtle
  • 2,038
  • 26
  • 20
  • Why not just use the `std::string` and forget about the `const char*`? (A `std::string` is just a `char*` wrapped in useful code to do stuff so you don't need to) – Galik Sep 23 '17 at 04:31
  • That "seemingly unnecessary" instance manages the dynamically allocated memory that `p` points to. In the second example, that memory is deallocated immediately, leaving `p` a dangling pointer. Same in the third example, just a bit more explicitly. – Igor Tandetnik Sep 23 '17 at 04:34
  • @Galik Yeah I'd love to, but an API I'm using requires a const char* as an input to some functions which I use a lot. – aquirdturtle Sep 23 '17 at 04:37
  • Just pass `s.c_str()` every time you call the `API` (that's what it's for). – Galik Sep 23 '17 at 04:38
  • The scope is the area where a name is visible. There is no scope issue here. Changed tags. – curiousguy Sep 23 '17 at 04:51
  • 1
    The variable `s` is not unnecessary. It is required to ensure the created `std::string` exists long enough that other code (like the API you're using) can safely use a pointer to its internals (such as that returned by `s.c_str()`). – Peter Sep 23 '17 at 04:59

4 Answers4

4

std::string encapsulates managing dynamic memory (created with new[] and delete[]). Let's break it down.

const char * p = std::to_string(num).c_str();
  1. Create a std::string (with a human-readable representation of num).
  2. Get the new[]ly allocated const char* to the string.
  3. Assign that value to p.
  4. Destroy the std::stringdelete[] the allocated const char*.
  5. p points to... deallocated data

If you are using a pointer, the data that the pointer points to must exist throughout the lifetime of that pointer.

So, no, there is no way around this other than new[]ing a copy of the string, which you will have to explicitly delete[] later. And at that point, you've thrown the baby out with the bath and have no need to use std::string.

Create a string that lives at least as long as you want to refer to its internal data.

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39
3

Just use std::string it does everything you want and everything that you would have to do manually if you don't use it.

When you need to pass a const char* to a const char* function simply use std::string::c_str() like this:

some_api_function(mystring.c_str()); // passes a const char*
Galik
  • 47,303
  • 4
  • 80
  • 117
0

What you need is a function which returns a char* which holds your value and can be used to manage its lifetime. The problematic version is broken because the char* points to memory which it does not manage.

For example:

std::unique_ptr<char[]> str(int32_t x)
{
    std::unique_ptr<char[]> res(new char[12]);
    snprintf(res.get(), 12, "%d", x);
    return res;
}
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
-1

Usestd::string everywhere and don't use const char* when not nessecary. They are basically the same thing. I use const char* only when I'm using a file-path. Use std::string everywhere and your program should work.

  • 3
    `using namespace STD` is not only a typo, it is inappropriate for use in header files (at global scope). Not a good suggestion. – John Zwinck Sep 23 '17 at 04:44
  • Sorry, Mr. John Saini. I figured it out, and I fixed it. Thanks for your down-votes and electric comments. – Aditya Chandra Sep 23 '17 at 12:10