Возврат '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 содержавший мусор. Я затем понял, что струна до, которую я получаю от функции, уничтожается, когда функция возвращается потому что std::ostringstream выделяется на стеке. Таким образом, я добавил:

return strdup( out.str().c_str());

И теперь я могу получить текст, в котором я нуждаюсь от функции.

У меня есть два вопроса:

  1. Я понимаю это правильно?

  2. Я позже заметил это out (типа std::ostringstream) был выделен со статическим устройством хранения данных. Разве это не означает, что объект, как предполагается, остается в памяти, пока программа не завершается? И если так, затем почему к строке нельзя получить доступ?

8
задан DavidRR 7 April 2015 в 12:09
поделиться

4 ответа

strdup размещает копию строки в куче, которую вы должны освободить вручную позже (я думаю, с помощью free () ) . Если у вас есть возможность, было бы гораздо лучше вернуть std :: string .

Статическое хранилище out не помогает, потому что .str () возвращает временный std :: string , который уничтожается, когда функция выходы.

11
ответ дан 5 December 2019 в 12:57
поделиться

В GetHandStateBrief переменная out не обязательно должна быть статической. Вам нужна явная статическая строка , чтобы заменить временное, которое было создано в вашем исходном вызове out.str () :

static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();
-1
ответ дан 5 December 2019 в 12:57
поделиться

strdup () возвращает указатель char *, указывающий на память в куче. Вам нужно освободить () его, когда вы закончите с ним, но да, это сработает.

Статическая локальная переменная std :: ostringstream out не имеет смысла в этом случае, если только возвращаемая std :: string не была также статической, что, как показывает ваше наблюдение, не соответствует действительности.

0
ответ дан 5 December 2019 в 12:57
поделиться

Вы правы, что out - это статическая переменная, размещенная в сегменте данных. Но out.str () временно размещен в стеке. Итак, когда вы выполняете return out.str (). C_str () , вы возвращаете указатель на временные внутренние данные стека. Обратите внимание, что даже если строка не является переменной стека, c_str «предоставляется только для того, чтобы оставаться неизменной до следующего вызова непостоянной функции-члена строкового объекта».

Я думаю, что вы ' Мы нашли разумный обходной путь, предполагая, что вы не можете просто вернуть строку.

3
ответ дан 5 December 2019 в 12:57
поделиться