Is It a Good Idea to Return " Const Char * " from a Function

Is it a good idea to return const char * from a function?

Depending on what somestlstring is and what is being done there.

If it is a local variable you are returning a pointer into memory that is being released when GetSomeString completes, so it is a dangling pointer and an error.

It all boils down to the lifetime of somestlstring and the operations you perform on it. The pointer returned by .c_str() is guaranteed to be valid only up to the next mutating operation in the string. So if something changes somestlstring from the call to .c_str() and before s is constructed you will be in undefined behavior land.

Problems returning const char* from function

First of all, you could simplify your code to the following:

    std::string myVar= "Return Message";
return RPC_Response(myVar.c_str());

This will not work though, because the result of c_str() gets invalidated when a string gets modified, including the string being destroyed.

The reason using a string literal works is because string literals are stored globally. (It's actually implementation defined, but typically it is done so)

// storing it in a char* variable first is equivalent
return RPC_Response("Return Message");

Assuming RPC_Response only accepts C-strings, you would have do to this:

#include <string.h>
...

std::string myVar = "Return Message";
char* str = strdup(myVar.c_str());
return RPC_Response(str);

Is it well-defined behavior to return a vector of const char*, filled inside a function

Yes, because SOMESTRING's scope (viz. value represented by that macro) belongs to static storage, i.e. string literals have full lifetime of the program execution. And that is your case here.


Here are various scenarios:

  • #define SOMESTRING "Hello World!"

    --> OK. String literals are stored in static storage & hence their lifetime is from program's beginning till end

  • const char* SOMESTRING = "Hello World!"

    --> OK. Same as above.

  • char SOMESTRING[] = "Hello World!";

    --> OK, iff it's declared in a static or extern scopes.

    --> BAD, if this array is declared within a function as a non-static.

  • char* SOMESTRING = new char[X]; strncpy(SOMESTRING, "Hello World!", N);

    --> OK, because the string's storage is now in free store (i.e. heap) & will remain so until it's deleted. The catch is that, the strings stored in vector have to be freed up later to prevent memory leak.

BTW, std::vector doesn't influence the define/undefine-ness of the behaviour; In this case here it depends on the C-style string literals only as illustrated above.

Passing const char * to file.open(), strange behavior

const char* GenerateFileName(int Instance_nth, int Input_nth)
{
string filename = to_string(Instance_nth);
filename += "_";
filename += to_string(Input_nth);
filename += ".txt";

return filename.c_str();
}

You're returning a pointer to the data internally stored by filename while it is destroyed with GenerateFileName's ending: the returned value is a dangling pointer, and your code is undefined behaviour.

What you can do is returning a std::string instead of const char*:

std::string GenerateFileName(int Instance_nth, int Input_nth)
{
string filename = to_string(Instance_nth);
filename += "_";
filename += to_string(Input_nth);
filename += ".txt";

return filename;
}

Usage would become:

file.open(GenerateFileName(3, 0).c_str());

What happens when assigning a string literal to a member const char* variable from within a constructor in C++?

So, is this valid? And why?

Yes, it's valid. Because string literals have static storage duration, wherever it appears (within the function body or not).

String literals have static storage duration, and thus exist in memory for the life of the program.

c++ does static allocation of string literals apply to any const char *

First, at which revision of C++ did that became the case?

Always been the case since C++ was standardised. String literals have static storage duration.

Second, does this extend to any "const char*" ?

Yes, if you the the returned object has static storage. But that's not the case in your example. res has automatic storage duration. Instead you can do:

const char* make_const_char_ptr() { 
static const char res [] = { 'a', 'b', 'c', '\0' };
return res;
}

and it's valid.



Related Topics



Leave a reply



Submit