Первый вариант не работает, потому что вы возвращаете указатель на объект стека, который будет уничтожен. (Вернее, вы возвращаете указатель на кучу памяти, которая будет удалена ().) Хуже того, он может даже работать некоторое время, если никто не перезаписывает память, что делает его очень трудным для отладки.
Далее, вы не можете вернуть const char *, если не вернете указатель на статическую строку, подобную этой:
const char *GetString()
{
return "a static string in DATA segment - no need to delete";
}
У вашего второго варианта есть проблема возврата памяти, выделенной с помощью new (), в программу на C, которая будет вызывать free (). Они могут быть несовместимы.
Если вы возвращаете строку в C, есть 2 способа сделать это:
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()
}
или
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
}
в зависимости от вашей политики обработки памяти.
Как правило, вы НЕ можете вернуть указатель или ссылку на автоматический объект в C ++. Это одна из распространенных ошибок, проанализированных во многих книгах по С ++.