Это из небольшой библиотеки, которую я нашел онлайн:
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
содержавший мусор. Я затем понял, что струна до, которую я получаю от функции, уничтожается, когда функция возвращается потому что std::ostringstream
выделяется на стеке. Таким образом, я добавил:
return strdup( out.str().c_str());
И теперь я могу получить текст, в котором я нуждаюсь от функции.
У меня есть два вопроса:
Я понимаю это правильно?
Я позже заметил это out
(типа std::ostringstream
) был выделен со статическим устройством хранения данных. Разве это не означает, что объект, как предполагается, остается в памяти, пока программа не завершается? И если так, затем почему к строке нельзя получить доступ?
strdup размещает копию строки в куче, которую вы должны освободить вручную позже (я думаю, с помощью free ()
) . Если у вас есть возможность, было бы гораздо лучше вернуть std :: string
.
Статическое хранилище out
не помогает, потому что .str ()
возвращает временный std :: string
, который уничтожается, когда функция выходы.
В GetHandStateBrief
переменная out
не обязательно должна быть статической. Вам нужна явная статическая строка
, чтобы заменить временное, которое было создано в вашем исходном вызове out.str ()
:
static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();
strdup () возвращает указатель char *, указывающий на память в куче. Вам нужно освободить () его, когда вы закончите с ним, но да, это сработает.
Статическая локальная переменная std :: ostringstream out
не имеет смысла в этом случае, если только возвращаемая std :: string не была также статической, что, как показывает ваше наблюдение, не соответствует действительности.
Вы правы, что out
- это статическая переменная, размещенная в сегменте данных. Но out.str ()
временно размещен в стеке. Итак, когда вы выполняете return out.str (). C_str ()
, вы возвращаете указатель на временные внутренние данные стека. Обратите внимание, что даже если строка не является переменной стека, c_str
«предоставляется только для того, чтобы оставаться неизменной до следующего вызова непостоянной функции-члена строкового объекта».
Я думаю, что вы ' Мы нашли разумный обходной путь, предполагая, что вы не можете просто вернуть строку.