2017-05-03 4 views
-1

Ich habe eine AVL-Struktur mit String-Schlüssel und meine eigene String-Klasse. Um ein anderes Problem zu beheben, musste ich einen Kopierkonstruktor zu String hinzufügen. Valgrind meldet jedoch einen Fehler damit. Hier ist der Konstruktor:C++ - Valgrind: Ungültige Schreiben der Größe 1

String::String(const String& s){ 
    try { 
     mStr = new char[1]; 
    } 
    catch (const bad_alloc& e){ 
     printf("ERROR: No memory\n"); 
     exit(0); 
    } 
    mStr[0]='\0'; 
    mCopy(s); 
} 

void String::mCopy(const String& s){ 
    // delete[] mStr; 
    size_t n = s.Length(); 
    try{ 
     mStr = new char[n + 1]; 
    } 
    catch (const bad_alloc& e){ 
     printf("ERROR: No memory\n"); 
     exit(0); 
    } 
    strcpy(mStr, s.mStr); 
    mStr[n + 1] = '\0'; 
} 

Und hier ist ein Teil von Valgrind ausgegeben, nachdem eine Zeichenfolge Schlüssel zu meinem AVL-Baum hinzu:

==7005== Invalid write of size 1 
==7005== at 0x4013A1: String::mCopy(String const&) (in /home/ezrafell/Desktop/DA2final/DA3.o) 
==7005== by 0x401213: String::String(String const&) (in /home/ezrafell/Desktop/DA2final/DA3.o) 
==7005== by 0x40182D: main (in /home/ezrafell/Desktop/DA2final/DA3.o) 
==7005== Address 0x5ad450d is 0 bytes after a block of size 61 alloc'd 
==7005== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==7005== by 0x40136B: String::mCopy(String const&) (in /home/ezrafell/Desktop/DA2final/DA3.o) 
==7005== by 0x401213: String::String(String const&) (in /home/ezrafell/Desktop/DA2final/DA3.o) 
==7005== by 0x40182D: main (in /home/ezrafell/Desktop/DA2final/DA3.o) 

Andere Fehler von Valgrind berichtet auch operator new[] in String::String(String const&) zurückverfolgen. Aber was ist daran falsch? Und wie schreibe ich den Konstruktor neu, um diesen Fehler zu vermeiden?

+0

Bitte poste ein [MCVE]. –

+0

Warum weist Ihr Konstruktor mStr einen Wert zu, ignoriert ihn und weist 'mStr' einen neuen Wert zu, indem er' mCopy' aufruft? Welchen Sinn macht das? Warum beendet 'mCopy' eine Zeichenfolge, die bereits beendet wurde? –

Antwort

3

Der Fehler wird durch diese Linie erzeugt:

mStr[n + 1] = '\0'; 

n+1 einer letzten der zugewiesenen Größe. Sie müssen n stattdessen verwenden, weil der Körper des Strings bei Indizes befindet sich 0 durch n-1, inklusive, so dass der Index n ist, wo Nullabschluss geht:

mStr[n] = '\0'; 

Hinweis diese Zeile entfernen richtig sein, auch, weil strcpy Null-endet sein Ergebnis. Wenn Sie Funktionen verwenden, die dies nicht für Sie tun, z. B. memcpy, müssen Sie den Nullabschluss manuell platzieren.

Verwandte Themen