The first variant doesn't work because you're returning a pointer into a stack object, which will get destroyed. (More presisely, you return a pointer to a heap memory, whch will have been deleted().) Worse still, it may even work for some time, if nobody's overwriting the memory, making it very hard to debug.
Next, you can not return a const char* unless you return a pointer to a static string like this:
const char *GetString()
{
return "a static string in DATA segment - no need to delete";
}
You second variant has the problem of returning memory allocated with new() into a C program that will call free(). Those may not be compatible.
If you return a string to C, there are 2 way to do that:
char *GetString()
{
std::stringstream ss;
ss << "The random number is: " << rand();
return strdup( ss.str().c_str() ); // allocated in C style with malloc()
}
void foo()
{
char *p = GetString();
printf("string: %s", p));
free( p ); // must not forget to free(), must not use delete()
}
or:
char *GetString(char *buffer, size_t len)
{
std::stringstream ss;
ss << "The random number is: " << rand();
return strncpy(buffer, ss.str().c_str(), len); // caller allocates memory
}
void foo()
{
char buffer[ 100 ];
printf("string: %s", GetString(buffer, sizeof( buffer ))); // no memory leaks
}
depending on you memory handling policy.
As a rule, you can NOT ever return a pointer or a reference to an automatic object in C++. This is one of common mistakes analyzed in many C++ books.