2016-01-01 14 views
22

Perché la dimensione di std::string, come determinato da sizeof(std::string), resa 8?
ho pensato che dovrebbe essere più che 8 in quanto deve avere un int (sizeof(int) == 8 sulla mia macchina) membro di dati per dare std::string::length() e std::string::size() in O (1) e, probabilmente, un char* per i caratteri.Perché sizeof (std :: string) ha solo otto byte?

+0

La tua domanda non è chiara, per favore riprova. –

+14

@self: è totalmente chiaro. Chiede perché sizeof (stringa)

+0

La risposta dipende probabilmente dal compilatore che si sta utilizzando. – freakish

risposta

18

Poiché tutta l'implementazione dei negozi std::string è un puntatore all'heap in cui sono memorizzati tutti i relativi dati.

+2

risposta semplice e migliore. – baash05

+0

Questo tipo di implementazione è semplice per le implementazioni 'std :: string' che usano il conteggio delle copie e dei riferimenti (libstdC++ lo ha fatto nella modalità AB + C++ 98 e le distribuzioni di Linux sono in procinto di sbarazzarsene come default adesso). C++ 11 ha reso questo tipo di implementazione illegale, quindi probabilmente troverai implementazioni con 'sizeof (std :: string) == sizeof (void *)' molto meno in futuro. –

26

L'implementazione di std::string non è specificata dallo standard C++. Descrive solo il comportamento delle classi. Tuttavia, mi aspetto che ci siano più informazioni di un puntatore nella classe. In particolare:

  • Un puntatore alla stringa effettiva.
  • La dimensione disponibile.
  • La dimensione effettiva utilizzata.

'MAGGIO di deposito naturalmente tutti questi in una posizione allocato dinamicamente, e quindi prendere esattamente la stessa quantità di spazio come char* [nella maggior parte delle architetture].

Infatti, guardando l'header C++ fornito con la mia macchina Linux, l'implementazione è abbastanza chiara quando si guarda (che, come per i commenti, è "pre-C++ 11", ma penso sia grossomodo rappresentativo andata):

size_type 
    length() const _GLIBCXX_NOEXCEPT 
    { return _M_rep()->_M_length; } 

e quindi seguire che a:

_Rep* 
    _M_rep() const _GLIBCXX_NOEXCEPT 
    { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); } 

che a sua volta porta a:

_CharT* 
    _M_data() const _GLIBCXX_NOEXCEPT 
    { return _M_dataplus._M_p; } 

che porta a

// Data Members (private): 
    mutable _Alloc_hider _M_dataplus; 

e poi si arriva a:

struct _Alloc_hider : _Alloc 
    { 
    _Alloc_hider(_CharT* __dat, const _Alloc& __a) _GLIBCXX_NOEXCEPT 
    : _Alloc(__a), _M_p(__dat) { } 

    _CharT* _M_p; // The actual data. 
    }; 

I dati reali circa la stringa è:

struct _Rep_base 
    { 
    size_type  _M_length; 
    size_type  _M_capacity; 
    _Atomic_word  _M_refcount; 
    }; 

Quindi, è tutto un semplice puntatore chiamato _M_p nascosto all'interno diversi strati di getter e un po 'di getti ...

+0

Per essere giusti, l'allocazione dinamica di solito può essere esclusa con metodi no-outs. Non penso che 'std :: string' abbia abbastanza requisiti per l'eccedenza. – Yakk

+1

Intendo, "insieme con la stringa stessa", piuttosto che ogni parte viene allocata dinamicamente. –

+0

@MarcGlisse: Penso che sia C++ 11, poiché proviene dalla versione 4.9.2 di gcc, che è conforme alla conformità C++ 11 in gcc e menziona C++ 11 nel file? –

Problemi correlati