2016-03-28 14 views
0

Der folgende Code soll meine eigene String-Klasse implementieren. Ähnlich wie wenn Sie so etwas erstellen würden String s = "Hi";. Ich bekomme einen Fehler, wenn es zu zerstören geht und zu dem Teil kommt, wo delete[] data. Is sagt, ich schreibe, wenn ich keinen Puffer mehr habe. Dies sind keine C-Strings, daher gibt es am Ende meiner Zeichenfolge kein Nullzeichen.Löschen eines Zeichenzeigers, der einen Heap-Fehler verursacht

Hier mein konvertieren/Standardkonstruktors:

String346::String346(const char * oldString) : data(NULL), size(static_cast<unsigned int>(strlen(oldString))){ 
    data = new(std::nothrow) char[size]; 
    for (unsigned int i = 0; i <= getSize(); i++){ 
     data[i] = oldString[i]; 
    } 
} 

Da diese Funktionen benötigen Funktion Verkettungs unterstützen werde ich meine beiden Funktionen setzen, die zu meinem Problem beziehen ein, wo, wenn ein String346 Objekt übergeben wurde oder wenn ein char * wurde bestanden

Funktion verketten wo char * in geben wird.

String346 & String346::concat(const char * catString) { 
    String346 newCatString(catString); 
    concat(newCatString); 
    return (*this); 
} 

verketten Funktion wo String346 Objekt übergeben wird:

String346 & String346::concat(const String346 & catString) { 
     String346 tempData(data); 
     size = tempData.getSize() + catString.getSize(); 
     destroy(); 
     data = new (std::nothrow) char[size]; 
     if (data == NULL){ 
      std::cout << "Not enough space to concatinate this string." << std::endl; 
     } 
     else{ 
      unsigned int index = 0; 
      for (unsigned int i = 0; i < getSize(); i++){ 
       if (i < tempData.getSize()){ 
        data[i] = tempData.data[i]; 
       } 
       else{ 
        data[i] = catString.data[index]; 
        index++; 
       } 
      }  
     } 
     return (*this); 
    } 

meine Funktion zerstören, die für die Zerstörung eines Objekts die ganze Arbeit tut, ist einfach. Sie enthält die folgenden drei Zeilen:

delete[] data; 
    data = NULL; 
    size = 0; 
    return; 

Antwort

1

Ihr Konstruktor ordnet eine char Array mit size Elemente.

Dann scheint Ihr Konstruktor size+1 Zeichen in das Array zu kopieren (ich nehme an, getSize() gibt size zurück).

Daher wird der Konstruktorcode über das Ende des Arrays ausgeführt und beschädigt ein Byte nach dem Ende des zugeordneten Arrays.

P.S. Die static_cast wird nicht benötigt und macht den Code nur verschleierter.

0

Die erste Zeile in Ihrer concat Methode:

String346 tempData(data); 

gibt einen char * zu Ihrem Konstruktor, der nicht null beendet wird, so der Aufruf an strlen vorbei am Ende der Schnur gehen.

Die nächsten beiden Zeilen funktionieren auch nicht:

size = tempData.getSize() + catString.getSize(); 
    destroy(); 

destroy Sätze auf Null size zurück, die der Rest der Methode bedeutet, nichts tun.

Sie sollten versuchen, dies durch einen Debugger und einen einzigen Schritt durchlaufen - Sie können dann die Werte Ihrer Variablen bei jedem Schritt überprüfen und sicherstellen, dass Ihr Programm das tut, was Sie erwarten.

Wenn Sie eine Membervariable haben, die im Destruktor freigegeben wird, sollten Sie in die "Regel der drei" oder "Regel der fünf" schauen, um sicherzustellen, dass die Dinge nicht zweimal freigegeben werden.