Frage Warum ist sizeof (string) == 32?


Wie hoch ist der Overhead in der String-Struktur, der bewirkt, dass sizeof () 32 ist?


15
2017-09-22 15:19


Ursprung


Antworten:


Etwas std::string Implementierungen speichern sehr kleine Zeichenketten direkt auf dem Stapel in einer statischen Größe char Array anstelle von dynamischen Heapspeicher. Dies ermöglicht es, Heap-Zuordnungen für viele kleine String-Objekte zu vermeiden und die Fundstelle zu verbessern.

Außerdem wird es eine std::size_t Mitglied, um die Zeichenfolgengröße und einen (möglicherweise unbenutzten, siehe oben) Zeiger auf den Heapspeicher zu speichern.


41
2017-09-22 15:21



std::string enthält in der Regel einen Puffer für die "small string optimization" --- wenn der String kleiner als die Puffergröße ist, ist keine Heap-Zuweisung erforderlich.


9
2017-09-22 15:22



Meine Vermutung ist:

class vector
{
    char type;
    struct Heap
    {
      char*   start;
      char*   end;
      char*   allocatedEnd;
    };
    struct Stack
    {
      char    size;
      char    data[27];
    }
    union
    {
        Stack   stackVersion;
        Heap    heapVersion;
    } version;
};

Aber ich wette, es gibt Hunderte von Möglichkeiten, dies zu tun.


4
2017-09-22 16:05



Es ist abhängig von der Bibliothek. Sie sollten sich nicht auf die Größe von verlassen std::string Objekte, weil es wahrscheinlich in verschiedenen Umgebungen (offensichtlich zwischen verschiedenen Standard-Bibliothek-Anbietern, sondern auch zwischen verschiedenen Versionen der gleichen Bibliothek) ändern wird.

Denk daran, dass std::string Implementierungen werden von Leuten geschrieben, die für eine Vielzahl von Anwendungsfällen optimiert wurden, was typischerweise zu 2 internen Repräsentationen führt, eine für kurze Strings (kleiner interner Puffer) und eine für lange Strings (haufenzugewiesener externer Puffer). Der Overhead ist damit verbunden, beide in jedem zu halten std::string Objekt.


3
2017-09-22 15:51



In g ++ 5.2 (z. B. g ++ 4.9, es ist anders) ist ein String grundsätzlich definiert als:

class string {
  char* bufferp;
  size_t length;
  union {
    char local_buffer[16];
    size_t capacity;
  };
};

Auf einem normalen Computer ergibt dies bis zu 32 Bytes (8 + 8 + 16).

Die eigentliche Definition ist natürlich

typedef basic_string<char> string;

aber die Idee ist dieselbe.


2
2018-03-17 00:07



F: Warum ist ein Hund gelb? A: Es ist nicht unbedingt.

Die Größe eines (an?) Std :: string-Objekts ist implementierungsabhängig. Ich habe gerade MS VC ++ 2010 überprüft. Es verwendet tatsächlich 32 Bytes für std :: string. Es gibt eine 16-Byte-Union, die entweder den Text der Zeichenfolge enthält, falls sie passt, oder einen Zeiger auf den Heapspeicher für längere Zeichenfolgen. Wenn sich die Implementierer dafür entschieden hätten, 18 Byte-Strings im String-Objekt und nicht im Heap zu behalten, wäre die Größe 34 Byte. Die anderen 16 Bytes umfassen Overhead, der solche Dinge wie die Länge der Kette und die Menge an Speicher enthält, die momentan für die Kette reserviert ist.

Eine andere Implementierung kann Speicher immer aus dem Heap zuordnen. Eine solche Implementierung würde zweifellos weniger Speicher für das String-Objekt benötigen.


1
2017-09-22 16:15