2017-02-16 3 views
1

Im folgenden Code:Warum führt der Sizeof-Operator in einer std :: string zu einem unerwarteten Ergebnis?

#include <iostream> 
#include <string> 
using namespace std; 

int main() { 
    char buff[100]; 
    _snprintf(buff, sizeof(buff), "%s %d", "Name",2); //snprintf incase of ideone 
    string buffAsStdStr = buff; 
    cout<<buffAsStdStr<<endl; 
    cout<<"len: "<<buffAsStdStr.length()<<endl; 
    cout<<sizeof(buffAsStdStr)<<endl; 

    return 0; 
} 

Die Länge der Zeichenfolge in buffAsStdStr 6, aber der Wert die sizeof Show ist 28, wenn ich in Visual Studio 2012 und 32 in ideone laufen. Die erwartete Größe ist 7 rechts einschließlich des abschließenden NULL-Zeichens.

Was ist der Grund für dieses unerwartete Ergebnis von sizeof operator? Warum ändert sich das Ergebnis zwischen Visual Studio und Ideone?

+5

Der Grund ist, dass Ihre Erwartungen falsch waren :) – StoryTeller

+0

Die Frage macht Sinn, besonders für jemanden, der C++ lernt. –

+2

@ Mr.C64 ja ich bin ein Anfänger. Jetzt verstanden und kristallklar. Danke euch allen! –

Antwort

7

sizeof einer std::string Instanz zurückgibt nur die Größe, in Bytes, der „interne Darstellung“ des std::string, dh Sie es wie die Summe der sizeof s jedes std::string ‚s Daten Mitglieder denken kann (es kann Padding beteiligt sein).

Zum Beispiel in 32-Bit-Debug-Builds mit VS2015, sizeof(std::string) gibt 28 zurück; in 64-Bit-Debug-Builds bekomme ich 40; in 32-Bit-Version I 24 baut erhalten und in 64-Bit-Version baut 32.

Das ist, weil die internen Darstellung std::string mit verschiedenen Build-Optionen verändert: z Debug-Builds enthalten in der Regel zusätzliche Mechanismen, um Fehler zu erkennen, wodurch die Größe der Darstellung wächst. außerdem in 64-Bit die Zeiger baut größer sind, so wiederum die Größe steigt in Bezug auf 32-Bit-Builds usw.

So ist die Zahl, die Sie von sizeof erhalten auf einer std::string Instanz aufgerufen wird im allgemeinen verschiedenen aus der Nummer char s, die den Text der Zeichenfolge bilden. Um diese Nummer zu erhalten, müssen Sie std::string::size or std::string::length anrufen.

+0

Interessant. Der kleine Zeichenfolgenpuffer ist eindeutig 16 Byte in Visual Studio. Ich bin ein wenig überrascht, dass sie es nicht 20 in einem 32-Bit-Build geschafft haben, so dass die Größe ein Vielfaches von 8 war. Vielleicht interessieren sie sich nicht mehr für 32-Bit-Builds. –

+0

@MartinBonner: In VS2015 ist 'sizeof (std :: string)' ** 24 ** (3x8) in 32-bit _release_ builds :) –

3

Sie sollten std::string::size, or std::string::length verwenden.

sizeof gibt die Größe des Objekts zurück, es ist nicht die Anzahl der enthaltenen Zeichen.

+0

std :: string :: size und std :: string :: length gibt das gleiche zurück. Als 6. –

+0

Ja. Es zählt keinen Nullabschluss. – ForEveR

+0

@ShameelMohamed Du verstehst es nicht wirklich, oder? –

3

Der Grund ist, dass sizeof(buffAsStdStr) nicht die Länge der Zeichenfolge ist, sondern die Größe der std::string Instanz, und jede Instanz eines bestimmten Typs hat die gleiche Größe.

Das Ergebnis sizeof während der Kompilierung bestimmt wird, und wenn Sie o vom Typ T ein Objekt haben, sizeof(o) und sizeof(T) gleichwertig sind.

Außerdem ist ein std::string nicht erforderlich, um ein abschließendes Nullzeichen zu speichern, und kann "nicht abschließende" Nullzeichen enthalten.

Verwandte Themen