Perché non è std :: string :: max_size () == std :: string :: :: allocator max_size ()

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

  •  22-09-2019
  •  | 
  •  

Domanda

Di recente ho notato che la seguente affermazione non è vera data std::string s.

s.max_size() == s.get_allocator().max_size();

Lo trovo interessante, per impostazione predefinita std::string utilizzerà std::allocator<char> che ha un limite teorico di size_type(-1) (sì lo so sto assumendo complemento a 2, ma che è estraneo alla domanda reale). So che le limitazioni pratiche sarà significativamente inferiore a questo. In un tipico 32 bit, x86, il kernel occuperà 2GB (forse 1 GB) dello spazio di indirizzi lasciando un limite superiore pratico molto più piccolo.

In ogni caso, GNU libstdc ++ std::basic_string<>::max_size() s 'sembra restituire lo stesso valore indipendentemente da ciò che l'allocatore si sta usando dice (qualcosa come 1073741820).

Quindi la domanda rimane, perché non std::basic_string<>::max_size() solo tornare get_allocator().max_size()? Mi sembra che questo sia il limite superiore ipotetica. E se l'allocazione arriva a breve, sarà solo gettare un std::bad_alloc, quindi perché non provare?

Questo è più di una curiosità che altro, mi stavo chiedendo il motivo per cui i due sono definiti separatamente in almeno questo implementazione.

È stato utile?

Soluzione

Microsoft Connect è stato inviato bug relativo alla tua domanda . Microsoft ha risposta interessante ad esso:

  

Abbiamo risolto come By Design secondo la nostra interpretazione della norma, che non spiega chiaramente ciò che lo scopo previsto per max_size () è. Allocatore max_size () è descritto come "il più grande valore che può essere passato significato di X :: allocate ()" (C ++ 03 20.1.5 [lib.allocator.requirements] / Tabella 32), ma contenitore max_size () è descritto come "size () del contenitore più grande possibile" (23,1 [lib.container.requirements] / Tabella 65). Nulla indica se e come contenitore max_size () dovrebbe essere derivato da allocatore max_size (). La nostra implementazione per molti anni è derivato max_size contenitore () direttamente dal max_size allocatore () e poi utilizzato questo valore per i controlli di overflow e così via. Altre interpretazioni della norma, come la vostra, sono possibili, ma non sono inequivocabilmente corretto per noi. La formulazione di standard potrebbe sicuramente beneficiare di chiarimento. A meno che e fino a quando ciò accade, abbiamo deciso di lasciare la nostra attuale implementazione invariato per due ragioni: (1) altri clienti possono essere a seconda del nostro comportamento attuale, e (2) MAX_SIZE () fondamentalmente non compra nulla. Al massimo, le cose che consumano ripartitori (come contenitori) potrebbe utilizzare allocatore max_size () per prevedere quando allocare () fallirà - ma semplicemente chiamando allocare () è un test migliore, dal momento che l'allocatore deciderà di dare la memoria oppure no. Le cose che consumano contenitori potrebbero usare max_size contenitore () come garanzia di quanto grande dimensione () potrebbe essere, ma una garanzia più semplice è la gamma di size_type.

qui si potrebbe trovare Nucleo Issue # 197. Il comitato ha ritenuto richiesta di migliorare la formulazione di standard, ma è stato rifiutato.

Quindi la risposta alla tua domanda: "Perché ..?" è che standard non spiega chiaramente ciò che lo scopo previsto per max_size () è.

Altri suggerimenti

Non sono del tutto sicuro, ma per quanto ne so std::basic_string non è limitata nello standard corrente per memorizzare la stringa nella memoria continua. Ad esempio, può conservarla in blocchi diversi. Ogni tale pezzo è quindi limitato a std::allocator::max_size() ma la somma potrebbe essere più grande di quello.

Inoltre sembra essere il caso con contenitori STL. E dopo tutto std::basic_string è un contenitore.

implementazione di GCC ha un commento come calcolano max_size (si deve sottrarre la dimensione dell'oggetto di pulizia interna che viene assegnata come un unico blocco con la stringa), e poi aggiunge che max_size() restituisce un quarto di quello. Non v'è alcuna giustificazione data, quindi forse si tratta solo di un margine di sicurezza? (Dovrebbe anche fornire una classe di corda, che forse si potrebbe usare per così tanto stringhe di grandi dimensioni?)

Con VC ++ max_size() restituisce uno in meno allocator.max_size() - probabilmente per tenere conto di terminazione carattere null.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top