Pergunta

int main(void)
{
   std::string foo("foo");
}

O meu entendimento é que o código acima usa o alocador padrão para chamar de novo. Assim, mesmo que o foo std :: string é alocado na pilha dentro buffer interno de foo é alocado no heap.

Como posso criar uma cadeia que é alocado inteiramente na pilha?

Foi útil?

Solução

Eu queria fazer exatamente isso me recentemente e achei o seguinte código esclarecedor:

stack_container.h

de Chronium

define um novo std::allocator que pode fornecer alocação baseada em pilha para a atribuição inicial de armazenamento para recipientes de STL. Acabei encontrando uma maneira diferente de resolver o meu problema particular, então eu realmente não utilizar o código de mim mesmo, mas talvez seja útil. Não se esqueça de ler os comentários no código em relação ao uso e advertências.

Para aqueles que questionaram a utilidade e sanidade de fazer isso, considere:

  • Muitas vezes você sabe a priori que a cadeia tem um tamanho máximo razoável. Por exemplo, se a cadeia está indo para armazenar um número inteiro de 32 bits formatado em decimal, você sabe que você não precisa de mais de 11 personagens para fazê-lo. Não há necessidade de uma cadeia que pode crescer dinamicamente para tamanho ilimitado nesse caso.
  • Alocação da pilha é mais rápido em muitos casos de alocar do heap.
  • Se a string é criada e destruída com frequência (suponho que é uma variável local em uma função de utilidade comumente usado), alocando da pilha em vez da pilha irá evitar a rotatividade de indução fragmentação no alocador de heap. Para aplicativos que usam muita memória, esta poderia ser uma virada de jogo.

Algumas pessoas têm comentado que a alocação de uma cadeia que usa pilha-baseado não será um std::string como se isso de alguma forma diminui a sua utilidade. É verdade, você não pode usar os dois alternadamente, para que você não será capaz de passar o seu stackstring às funções que esperam um std::string. Mas (se você fizer isso direito), você vai ser capaz de usar todas as mesmas funções de membro em seu stackstring que você usa agora std::string, como find_first_of(), append(), etc. begin() e end() continuará a funcionar bem, então você vai ser capaz de usar muitos dos algoritmos STL. Claro, ele não será std::string no sentido mais estrito, mas ainda será uma "string" no sentido prático, e ainda vai ser bastante útil.

Outras dicas

O problema é que std::basic_string tem um parâmetro de modelo para o alocador. Mas std::string não é um modelo e não tem parâmetros.

Assim, você poderia em uso princípio, uma instanciação de std::basic_string com um alocador que a memória usos na pilha, mas não seria um std::string. Em particular, você não iria ficar polimorfismo em tempo de execução, e você não poderia passar os objetos resultantes em funções que esperam um std::string.

Você não pode. Exceto ...

std::string é uma instância de

std::basic_string<class CharType, 
                  class Traits=char_traits<CharType>, 
                  class Allocator=allocator<CharType> >

Você pode conseguir definir uma classe alocador que usa alloca para gerenciamento de memória. Isso só funcionaria se o próprio alocador, e os métodos basic_string que invocá-lo direta ou indiretamente, são todos inline. Um objeto basic_string criado com este alocador não iria ser a std::string, mas se comportaria (principalmente) como ele. No entanto, isso seria uma boa quantidade de trabalho para ganhos limitados. Especificamente, usando esta classe para valores de retorno de uma função seria uma medida de limitação carreira.

Eu não tenho idéia por você ou alguém iria querer fazer isso.

Eu suspeito que fazer tal coisa que um seria difícil de fazer, eu me pergunto por que você quer fazer isso? Para alocar algo inteiramente na pilha, as necessidades do compilador saber em tempo de compilação que o tamanho exato da coisa é - no seu exemplo, seria necessário saber não apenas o tamanho dos metadados std::string, mas também o tamanho dos dados de seqüência em si. Isto não é muito flexível, você provavelmente precisa de diferentes tipos de cordas, dependendo do tamanho dos dados de cadeia que você está querendo incluir nele - não que isso seria impossível, você só tenderia a coisas complicar um pouco.

  • std :: string será sempre gerenciar é de armazenamento interno com novo / excluir.
  • Não sei por que a sua pergunta contém implementação corda do glibc . A implementação de string da biblioteca C ++ padrão não tem nada a ver com o glibc .
  • A única maneira de armazenar uma string na pilha é usar uma matriz C de char na pilha (como o que Shhnap delineado). Mas isso não é provavelmente o que você quer de qualquer maneira: -)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top