Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » delete problem - invalid pointer

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
13.10.2011, 17:05 Uhr
arcticlord



Hi,

Ich habe momentan ein kleines Verstaentnis Problem beim freigeben von Speicher bei char Arrays.
Im Prinzip suche ich nach einer guten Erklaerung warum im folgenden Beispiel die zweite delete anweisung einen (invalid pointer)-Programmstop produziert.


C++:
class Test{
    public:
    Test(const char * t);
    ~Test();
    const char * getText();
    private:
    const char * text;
};

Test::Test(const char * t){ text = t; }
Test::~Test(){ delete(text); }
const char * Test::getText(){ return text; }


int main (){
    char * buff = new char[100];
    buff[0] = 'b';
    buff[1] = 'l';
    buff[2] = 'a';
    buff[3] = '\0';

    Test* t1 = new Test(buff);
    printf("%s\n",t1->getText());
    delete(t1);   // funktioniert

    Test* t2 = new Test("bla");
    printf("%s\n",t2->getText());
    delete(t2);  // funktioniert nicht

    return 0;
}



thx 4 answers
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
13.10.2011, 17:44 Uhr
Lensflare



Hi arcticlord,

ich habe hier vor einiger Zeit mal eine ähnliche Frage gestellt:
www.fun-soft.de/showtopic.php?threadid=20656&

Also zunächst einmal braucht man "bla" nicht freizugeben. Im verlinkten Thread steht warum.

Außerdem ist es nicht sehr sinnvoll den Text im Destruktor der Klasse freizugeben, weil er ja nicht in der Klasse erzeugt wird, sondern außerhalb.
Also besser wäre es, ihn dann auch außerhalb freizugeben.

Und da du ja C++ Code schreibst und nicht C Code, wäre es hier auch sehr empfehlenswert, die Klasse std::string aus der Standardbibliothek zu verwenden, statt char arrays.
Das erspart dir viele Probleme.

Wenn du dennoch mit dynamisch (über new) erstellten char arrays arbeiten willst und deine klasse den text selbst löschen soll, dann sollte deine klasse den text, den sie über den konstruktor bekommt, mit z.B. strcpy() kopieren. dann kann sie ihn auch selbst wieder freigeben.
Denn sonst, wenn sie nur den zeiger lagert, ist unklar ob sie ihn löschen darf, denn jemand anders könnte ja auch einen zeiger auf diesen text haben. Aber wie gesagt, lieber std::string nehmen ^^
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)

Dieser Post wurde am 13.10.2011 um 18:40 Uhr von Lensflare editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
13.10.2011, 20:02 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


um Lensflare genauer auszuführen:


C++:
char* buff= new char[100];
//...
Test* t1 = new Test(buff);



hier übergibst du Test ja einen pointer, den du intern direkt speicherst, statt den inhalt zu kopieren.
darum geht das delete auf t1 noch.


C++:
Test* t2 = new Test("bla");



hier übergibst du jedoch einen konstanten zeiger, den man nicht löschen darf/kann!
daher stürzt das delete auf t2 ab.

Ansonsten hast du natürlich noch einen Fehler:


C++:
Test::~Test(){ delete(text); }



sollte wohl besser


C++:
Test::~Test(){ delete[] text; }



lauten, da du ja nicht nur ein einzelnes zeichen hast, sondern ein array - sonst erzeugst du speicherlöcher!

Was Lensflare meinte:

C++:
class Test{
    public:
    Test(const char * t);
    ~Test();
    const char * getText();
    private:
    const char * text;
};

Test::Test(const char * t)
{
   text = new char[strlen(t)+1]; // vorsicht! wenn t NULL ist, stürzt das ab!
   strcpy(text, t); // text in den eigenen speicher kopieren
}
Test::~Test(){ delete[] text; } // hier dürfen wir das dann auch freigeben, da wir es selbst angelegt haben
const char * Test::getText(){ return text; }



Einfacher wärs natürlich, einfach std::string zu benutzen, dann kann man sich das pointer geschubse sparen
--
class God : public ChuckNorris { };

Dieser Post wurde am 13.10.2011 um 20:03 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: