Come faccio a allocare una std :: string sullo stack tramite implementazione stringa di glibc?

StackOverflow https://stackoverflow.com/questions/783944

Domanda

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

La mia comprensione è che il codice precedente utilizza l'allocatore di default di chiamare di nuovo. Così, anche se il foo std :: stringa viene allocata sullo stack buffer interno interno foo è allocato sul mucchio.

Come posso creare una stringa che viene interamente allocato sullo stack?

È stato utile?

Soluzione

Ho voluto fare proprio questo io stesso di recente e ho trovato il seguente codice illuminante:

stack_container.h di Chronium

Si definisce un nuovo std::allocator che può fornire allocazione stack-based per l'assegnazione iniziale di stoccaggio per contenitori STL. Finii per trovare un modo diverso per risolvere il mio problema particolare, quindi non ho fatto uso il codice me stesso, ma forse sarà utile a voi. Non essere sicuri di leggere i commenti nel codice in materia di utilizzo e avvertimenti.

Per coloro che hanno messo in dubbio l'utilità e la sanità mentale di fare questo, prendere in considerazione:

  • Spesso si sa a priori che la stringa ha una dimensione massima ragionevole. Ad esempio, se la stringa sta per memorizzare un intero a 32 bit decimale-formattato, lo sai che non hai bisogno di più di 11 caratteri per farlo. Non v'è alcun bisogno di una stringa che può crescere in modo dinamico a misura illimitata in quel caso.
  • L'allocazione dalla pila è più veloce in molti casi di assegnazione dal mucchio.
  • Se si crea la stringa e distrutto frequentemente (supponiamo che è una variabile locale in una funzione di utilità comunemente utilizzati), ripartizione dalla pila invece del mucchio eviterà zangola frammentazione inducono nel allocatore mucchio. Per le applicazioni che utilizzano molta memoria, questo potrebbe essere un punto di svolta.

Alcune persone hanno commentato che una stringa che utilizza l'assegnazione stack-based non sarà un std::string come se questa diminuisce in qualche modo la sua utilità. È vero, non è possibile utilizzare i due in modo intercambiabile, in modo da non essere in grado di passare il vostro stackstring alle funzioni in attesa di un std::string. Ma (se lo fate a destra), si sarà in grado di utilizzare tutte le stesse funzioni membro sul stackstring di utilizzare ora in std::string, come find_first_of(), append(), ecc begin() e end() continuerà a funzionare bene, così sarete in grado di utilizzare molti degli algoritmi STL. Certo, non sarà std::string in senso stretto, ma sarà ancora una "stringa" in senso pratico, e sarà ancora molto utile.

Altri suggerimenti

Il problema è che std::basic_string ha un parametro di modello per l'allocatore. Ma non std::string è un modello e non ha parametri.

Quindi, si potrebbe in linea di principio utilizzare un'istanza di std::basic_string con un allocatore che utilizza la memoria sullo stack, ma non sarebbe una std::string. In particolare, non si otterrebbe runtime il polimorfismo, e non si poteva passare gli oggetti risultanti in funzioni in attesa di un std::string.

Non è possibile. Tranne ...

std::string è un'istanza di

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

Si potrebbe plausibilmente definire una classe Allocatore che utilizza alloca per la gestione della memoria. Ciò funziona solo se l'allocatore in sé, ei metodi basic_string che richiamano direttamente o indirettamente, sono tutti inline. Un oggetto basic_string creato con questo allocatore non sarebbe essere un std::string, ma sarebbe comportarsi (per lo più) di simile. Tuttavia, questa sarebbe una buona dose di lavoro per i guadagni limitati. Specificamente, utilizzando questa classe per restituire valori da una funzione sarebbe una mossa carriera limitativo.

Non ho idea di perché tu o chiunque altro vorrebbe fare questo.

Ho il sospetto che facendo una cosa del genere sarebbe difficile da fare, mi chiedo perché si vuole farlo? Per allocare qualcosa di completamente in pila, il compilatore ha bisogno di sapere al momento della compilazione ciò che la dimensione esatta della cosa è - nel tuo esempio avrebbe bisogno di conoscere non solo la dimensione dei metadati std::string, ma anche la dimensione dei dati di stringa si. Questo non è troppo flessibile, si sarebbe probabilmente bisogno di diversi tipi di stringhe a seconda delle dimensioni dei dati di stringa che si vogliono includere in essa - non che sarebbe impossibile da fare, basta tenderebbe a complicare le cose un po '.

  • std :: string riesca sempre è memoria interna con il nuovo / delete.
  • Non certo perché la tua domanda contiene implementazione stringa di glibc . L'implementazione di stringa del libreria standard C ++ non ha nulla a che fare con glibc .
  • L'unico modo per memorizzare una stringa in pila è di utilizzare un array C char in pila (come quello descritto Shhnap). Ma che probabilmente non è ciò che si vuole in ogni caso: -)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top