sizeof(irgendein string) = 4 warum ??



  • Hallo
    Wenn ich sizeof auf unterschiedlich lange strings anwende, bekomme ich immer 4 zurück. Eigentlich müsste doch der längere String mehr Platz benötigen. Woran liegt das ?

    Mein Programm:

    #include <string>
    #include <iostream>
    using namespace std;
    
    int main() {
    	string str1="te";
    	string str2="ich bin ein wirklich gaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanz endlos laaaaaaanger teststring";
    	cout << "sizeof 1. String: " << sizeof(str1) << "\n";
    	cout << "sizeof 2. string: " << sizeof(str2);
    	return 0;
    }
    

    Ausgabe:

    sizeof 1. String: 4
    sizeof 2. string: 4

    Danke für alle Antworten
    Michael



  • Weil string eine Klasse ist und die ist halt 4 bytes gross. Das weist darauf hin, das sie nur einen Pointer auf irgentwas beinhaltet (32 bit pointer == 4 bytes).



  • sizeof gibt die statische Größe der Klasse zurück. Die Methode size oder length ist eher was du brauchst.



  • Am besten versteht man es, wenn man es an einer eigenen Rumpfklasse MyString (nachfolgende nicht fehlerfrei! s.u.) ausprobiert:

    #include <iostream>
    #include <iomanip>
    #include <conio.h>
    #include <cstring>
    
    class MyString
    {
    public:
      MyString(char* pText=NULL);
      MyString(const MyString& str);               // Copy-Konstruktor
      MyString& operator=(const MyString& str);    // Zuweisungsoperator
      ~MyString();                                 // Destruktor
    private:
      char* pText_; // Zeiger auf die Daten im freestore
    };
    
    MyString::MyString(char* pText)
    {
      if (pText)
      {
        pText_ = new char[ strlen(pText+1) ];
        strcpy(pText_, pText);
      }
      else
      {
        pText_ = new char[1];
        *pText_='\0';
      }
    }
    
    MyString::MyString(const MyString& str)            // Copy-Konstruktor
    {
      pText_ = new char[ strlen(str.pText_+1) ];
      strcpy(pText_, str.pText_);
    }
    
    MyString& MyString::operator=(const MyString& str) // Zuweisungsoperator (falsch! Fehlt noch einiges, vor allem delete, s.u.)
    {
      pText_ = new char[ strlen(str.pText_+1) ];
      strcpy(pText_, str.pText_);
      return *this; // Unterschied zum Copy-Konstruktor
    }
    
    MyString::~MyString()
    {
      delete[] pText_;
    }
    
    int main()
    {
        MyString str1= "te"; 
        MyString str2= "ich bin ein wirklich gaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaanz endlos laaaaaaanger teststring"; 
        std::cout << "sizeof 1. String: " << sizeof(str1) << "\n"; 
        std::cout << "sizeof 2. string: " << sizeof(str2); 
        getch();
    }
    


  • Get the length of a string.

    Routine Required Header

    strlen <string.h> 
    wcslen <string.h> 
    
    size_t strlen( const char *string );
    size_t wcslen( const wchar_t *string );
    


  • Erhard Henkes schrieb:

    MyString& MyString::operator=(const MyString& str) // Zuweisungsoperator
    {
    pText_ = new char[ strlen(str.pText_+1) ];
    strcpy(pText_, str.pText_);
    return *this; // Unterschied zum Copy-Konstruktor
    }

    Das gibt ein schönes Speicherleck. 🙄



  • Sorry! Habe auf die Schnelle ein Zwischenstadium einer Schulungsklasse MyString erwischt, das zeigen soll, wie op= nicht arbeiten darf und wo der Unterschied zum copycon ist. Ich hoffe, dass ich hier eine halbwegs komplette Version erwischt habe, die aber immer noch schwere Designmängel hat, wie gesagt verschiedene Entwicklungsstufen:

    class MyString
    {
      private:
        char * pData_;
    
      public:
        friend MyString operator+( const MyString &, const MyString & );
        MyString() : pData_( NULL ) {} // inline ctor
        MyString( const char * pText );
        MyString( const MyString & text ); // Copy-Konstruktor
        ~MyString(); // dtor
        const MyString & operator=( const MyString & text );
    
        bool operator==( const MyString & text ) const;
        char operator[]( int index ) const;
        operator const char * () const; // cast zum C-String
        int getLaenge() const;
        void ausgeben() const;
    };
    
    MyString operator+( const MyString & leftstring, const MyString & rightstring );
    
    /******************************************************************/
    
    // ctor mit C-String als Argument
    MyString::MyString( const char * pText ) : pData_( NULL )
    {
      if( pText )
      {
        pData_ = new char[ strlen( pText ) + 1 ];
        strcpy( pData_, pText );
      }
    }
    
    // copy-ctor
    MyString::MyString( const MyString & text ) : pData_( NULL )
    {
      if( text.pData_ )
      {
        pData_ = new char[ strlen( text.pData_ ) + 1 ];
        strcpy( pData_, text.pData_ );
      }
    }
    
    // dtor
    MyString::~MyString() 
    {
      delete[] pData_;
    }
    
    // ==
    bool MyString::operator==( const MyString & text ) const
    {
      if( pData_ == NULL || text.pData_ == NULL )
      {
        return ( pData_ == NULL && text.pData_ == NULL );
      }
      return ( strcmp( pData_, text.pData_ ) == 0 );
    }
    
    // []
    char MyString::operator[]( int i ) const
    {
      if( i >= 0 && i < getLaenge() )
      {
        return pData_[i];
      } 
      else
      {
        return '\0';
      }
    }  
    
    // Länge des Textes ermitteln
    int MyString::getLaenge() const
    {
      if( pData_ == NULL )
      {
        return 0;
      }
      else
      {
        return strlen( pData_ );
      }
    }
    
    // cast zu C-String
    MyString::operator const char * () const
    {
      return pData_;
    }
    
    // Zuweisungs-Operator
    const MyString & MyString::operator=( const MyString & text ) 
    {
      if( this == &text ) // Selbstzuweisung abfangen
      {
        return *this;
      }  
      delete[] pData_;
      if( text.pData_ )
      {
        pData_ = new char[ strlen( text.pData_ ) + 1 ];
        strcpy( pData_, text.pData_ );
      }
      else
      {
        pData_ = NULL;
      }
      return *this; 
    }
    
    void MyString::ausgeben() const
    {
      cout << pData_ << endl;
    }
    
    /******************************************************************/
    
    MyString operator+( const MyString & leftstring, const MyString & rightstring )
    {
      MyString result;
      if( leftstring.pData_ != NULL && rightstring.pData_ != NULL )
      {
        result.pData_ = new char[ strlen( leftstring.pData_ ) + 
                                  strlen( rightstring.pData_ ) + 1 ];
        strcpy( result.pData_, leftstring.pData_ );
        strcat( result.pData_, rightstring.pData_ ); 
      } 
      else if( rightstring.pData_ != NULL )
      {
        result = rightstring;
      }
      else if( leftstring.pData_ != NULL )
      {
        result = leftstring;
      }
      return result;
    }
    


  • Wenn wir schon beim konkreten Experimentieren sind:

    Hier kann man auch sehr schön zeigen, wie ein zweiter Zeiger (nämlich der vptr auf die vtbl) hinzukommt, wenn man in der MyString-Klasse

    virtual ~MyString(); // dtor
    

    schreibt und den Destruktor damit virtual macht.

    Nun erhöht sich dies pro Objekt auf 8 Byte!


Anmelden zum Antworten