Возвращение c_str из функции
Это из небольшой библиотеки, которую я нашел в Интернете:
const char* GetHandStateBrief(const PostFlopState* state)
{
static std::ostringstream out;
// ... rest of the function ...
return out.str().c_str()
}
В моем коде я делаю это:
const char *d = GetHandStateBrief(&post);
std::cout<< d << std::endl;
Сейчас на первых порах d
содержал мусор. Затем я понял, что строка C, которую я получаю от функции, уничтожается, когда функция возвращается, потому что std::ostringstream
размещается в стеке. И я добавил:
return strdup( out.str().c_str());
И теперь я могу получить нужный мне текст из функции.
У меня есть два вопроса:
Я правильно понимаю?
Я позже заметил, что
out
(типаstd::ostringstream
) было выделено статическое хранилище. Не означает ли это, что объект должен оставаться в памяти до завершения программы? И если так, то почему нельзя получить доступ к строке?
4 ответа
strdup выделяет копию строки в куче, которую вы должны вручную освободить позже (с помощью free()
Я думаю). Если у вас есть возможность, было бы гораздо лучше вернуться std::string
,
Статическое хранилище out
не помогает, потому что .str()
возвращает временный std::string
, который уничтожается при выходе из функции.
Ты прав что out
статическая переменная, расположенная в сегменте данных Но out.str()
является временным размещением в стеке. Итак, когда вы делаете return out.str().c_str()
вы возвращаете указатель на внутренние данные временного стека. Обратите внимание, что даже если строка не является переменной стека, c_str
"предоставляется только для того, чтобы оставаться неизменным до следующего вызова неконстантной функции-члена строкового объекта".
Я думаю, что вы нашли разумный обходной путь, предполагая, что вы не можете просто вернуть строку.
strdup() возвращает указатель char*, который указывает на память в куче. Вам нужно освободить (), когда вы закончите с этим, но да, это сработает.
Статическая локальная переменная std::ostringstream out
в этом случае не имеет смысла, если только возвращаемая строка std::string не является статической, что, как показывает ваше наблюдение, не соответствует действительности.
В GetHandStateBrief
переменная out
не должен быть статичным. Вам нужен явный static string
заменить временный, который был создан в вашем исходном вызове out.str()
:
static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();