Pergunta

Isso é de uma pequena biblioteca que encontrei online:

const char* GetHandStateBrief(const PostFlopState* state)
{
    static std::ostringstream out;

    // ... rest of the function ...

    return out.str().c_str()
}

No meu código, estou fazendo isso:

const char *d = GetHandStateBrief(&post);
std::cout<< d << std::endl;

Agora, a princípio d continha lixo. Eu então percebi que a sequência C que estou recebendo da função é destruída quando a função retorna porque std::ostringstream é alocado na pilha. Então eu adicionei:

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

E agora posso obter o texto de que preciso da função.

Eu tenho duas perguntas:

  1. Estou entendendo isso corretamente?

  2. Mais tarde notei isso out (do tipo std::ostringstream) foi alocado com armazenamento estático. Isso não significa que o objeto deve permanecer na memória até que o programa termine? E se sim, então por que a string não pode ser acessada?

Foi útil?

Solução

STRDUP aloca uma cópia da string na pilha, que você deve libertar manualmente mais tarde (com free() Eu penso). Se você tiver a opção, seria muito melhor retornar std::string.

O armazenamento estático de out não ajuda, porque .str() retorna um temporário std::string, que é destruído quando a função sai.

Outras dicas

Você está certo isso out é uma variável estática alocada no segmento de dados. Mas out.str() é um alocado temporário na pilha. Então, quando você faz return out.str().c_str() Você está retornando um ponteiro para os dados internos de uma pilha temporária. Observe que mesmo que uma string não seja uma variável de pilha, c_str é "concedido apenas para permanecer inalterado até a próxima chamada para uma função de membro não constante do objeto String".

Eu acho que você acertou em uma solução alternável razoável, supondo que você não possa simplesmente devolver uma string.

strdup () retorna um ponteiro char* que está apontando para a memória na pilha. Você precisa libertá -lo quando terminar, mas sim, isso funcionará.

A variável local estática std::ostringstream out Nesse caso, não faz sentido, a menos que a string std :: retornasse também foi estática, que sua observação está mostrando que não é verdadeira.

Dentro GetHandStateBrief, variável out não precisa ser estático. Você precisa de um explícito static string para substituir o temporário que estava sendo criado em sua chamada original para out.str():

static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top