Возвращение 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());

И теперь я могу получить нужный мне текст из функции.

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

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

  2. Я позже заметил, что 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();
Другие вопросы по тегам