Pointer zu Character-Array / Speicherbelegung



  • Hallo,
    ich habe eine Frage zur Funktion c_str(), welche mir einen char-pointer zu einer string-variable liefert.
    In dem folgenden Beispiel lasse ich den Pointer bewusst über das char-array hinauslaufen.

    #include<iostream>;
    #include<string>;
    
    using namespace std;
    
    int main(){
    	string a="teststring";
    	const char* b=a.c_str();
    	char* c=new char[100];
    	for(int i=0; i<100;i++){
    		c[i]=b[i];}
    	for(int i=0; i<100;i++){	
    			cout << c[i];}
        delete []c;
    
    }
    

    Ich erhalte als output in der commandozeile:

    teststringteststringteststringteststringteststring
    

    Kann mir jemand erklären, warum der String fünfmal im Speicher präsent ist, und warum für 50 characters 100 konsekutive bytes belegt werden?

    Vielen Dank!



  • Vielleicht liegt der Speicher für dein char-Array direkt hinter dem Speicher den die String-Klasse angelegt hat. Und wenn du mit dem Zeiger durchläufst kopierst du sozusagen zuerst die Zeichen aus dem String, dann läufst du auf das Array auf und kopierst die eben gerade reingeschriebenen Zeichen nochmal dahinter usw. usw.

    Ist konsekutiv etwas schweinisches? 😃



  • Martin2000 schrieb:

    Kann mir jemand erklären, warum der String fünfmal im Speicher präsent ist, und warum für 50 characters 100 konsekutive bytes belegt werden?

    Du liest über das Array b hinaus, das ist undefiniert und dein Programm darf machen was es will.



  • Okay, vielen Dank für diese Antworten. Meine Frage entstand aus folgender Überlegung. Ich arbeite zur Zeit mit Bruce Eckel's Buch "Thinking in C++".

    Hier wird im 4ten Kapitel ein Object eingeführt, dass unter anderem die folgende Funktion besitzt:

    int Stash::add(const void* element) {
      if(next >= quantity) // Enough space left?
        inflate(increment);
      // Copy element into storage,
      // starting at next empty space:
      int startBytes = next * size;
      unsigned char* e = (unsigned char*)element;
      for(int i = 0; i < size; i++)
        storage[startBytes + i] = e[i];
      next++;
      return(next - 1); // Index number
    }
    

    Nun gibt es hierzu einen Beispielaufruf:

    ifstream in("CppLibTest.cpp");
      string line;
      while(getline(in, line))
        Stash.add(line.c_str());
    

    Hierzu muss noch gesagt werden, dass die Variable size=80 beträgt und 'storage' ein char-array mit freiem Speicher ab [startBytes ist.
    Wenn nun die eingelesene Zeile "CppLibTest.cpp" nicht 80 Zeichen besitzt, wird dann durch den counter 'i < size' (Zeile 😎 nicht automatisch auch Müll in den Speicher geladen?



  • Oder du hast eine speicherverschwendende std::string -Implementierung. :p
    Nein, undefiniertes Verhalten ist nicht immer trivial erklärbar. Achte einfach darauf, dass du dich nicht etwa auf solche Eigenschaften verlässt. Das Programm dürfte auch ohne Weiteres abstürzen oder noch Schlimmeres veranstalten.

    Mitleid schrieb:

    Ist konsekutiv etwas schweinisches? 😃

    Nein, das bedeutet etwa so viel wie "aufeinanderfolgend". 😉

    Edit:

    Martin2000 schrieb:

    Wenn nun die eingelesene Zeile "CppLibTest.cpp" nicht 80 Zeichen besitzt, wird dann durch den counter 'i < size' (Zeile 😎 nicht automatisch auch Müll in den Speicher geladen?

    Doch. Die Funktion ist sowieso eher böse, nur schon wegen des void* und Casts zu unsigned char . Keine Ahnung, was damit bezweckt wird...



  • Nexus schrieb:

    Nein, das bedeutet etwa so viel wie "aufeinanderfolgend". 😉

    Schlauberger sind verdammt unbeliebt! 😃 😃
    Aber, Danke, dass du es erklärt hast.


Anmelden zum Antworten