2012-03-25 8 views
1

Ist das sicher so etwas wie dies zu tun:Spielen mit char-Array

char* charArray = new char[10]; 
strcat(charArray, "qwertyuiop"); 
charArray[3] = '\0'; 
delete [] charArray; 

Will alles gelöscht? Oder das was nach \0 wird nicht sein? Ich weiß nicht, ob ich Müll verlasse.

EDIT: strcpy

+0

Machen Sie einen Verweis auf charArray [20] und sehen Sie den Wert nach dem Löschen [] – gaussblurinc

+3

Der Aufruf von strcat führt zu Undefined Behavior - danach sind alle Wetten aus. –

+1

Paul R bezieht sich auf die Tatsache, dass es unbekannt ist, wo das erste '\ 0' in dem Speicher ist, auf den' charArray' zeigt, da 'strcat's Funktionalität davon abhängt, das zu finden. – Eric

Antwort

5

sein sollte Wenn Sie schreiben strcpy statt strcat wollen, dann ist das sicher und richtig ist. Aber es scheint, dass Sie ein Missverständnis über delete [] charArray haben. Es löscht keine Zeichen, es löscht den Speicher, auf den charArray zeigt. Der Speicher selbst nach delete [] charArraykönnte enthalten diese Zeichen, es ist jedoch nicht garantiert.

Wenn Sie jedoch wirklich schreiben strcat wollte, und es ist kein Tippfehler, dann ruft der Code nicht definiertes Verhalten, weil charArray enthält Müll, die strcat versuchen wird, den zweiten String zu verketten.

+1

Es sollte 'strcpy' - typo sein. – user1112008

+0

Die 'strcat()' in einem nicht initialisierten Array ist sicherlich ** nicht ** in Ordnung. –

+1

@dasblinkenlight: Eingebaute Typen werden nicht so initialisiert. Wenn Sie es initialisieren wollen, müssen Sie 'new char [N]()' schreiben. Beachten Sie das '()' im neuen Ausdruck. – Nawaz

2

Nein, das ist in Ordnung, das gesamte Array ist gelöscht. delete schaut nicht auf den Zeiger, auf den Sie zeigen. Solange Sie new mit delete und new[] mit delete[] übereinstimmen, wird die richtige Menge an Speicher freigegeben.

(Aber betrachten std::string anstelle von char-Arrays verwendet wird, dass es eine Reihe von Fehlern wie das vermeiden Sie hat es über das Ende Ihrer Array zu schreiben.)

7

Abgesehen von der Tatsache, dass new[] für POD -types 0 initialisiert nicht das Array und strcat würde die abschließende '\0' nach dem Ende des zugewiesenen Bereichs schreiben, alles sieht gut aus: insbesondere wird delete den gesamten Block löschen.

Der Grund für das Schreiben nach dem Ende des zugewiesenen Blocks ist, dass die 10-stellige Zeichenfolge "qwertyuiop" 11 Byte zum Speichern benötigt.

+0

'charArray' ist nicht initialisiert. 'strcat' hängt das Wort an den Müll an und überschreibt wahrscheinlich mehr als nur das eine Byte. Verhalten ist nicht definiert. – bames53

+0

Die Objekte sind standardmäßig initialisiert, aber für primitive Typen bedeutet das nicht, dass sie initialisiert werden. Siehe [dcl.init] 8.5/6. Der zutreffende Fall ist "es wird keine Initialisierung durchgeführt". – bames53

+0

@ bames53 Sehr interessant! Ich habe die Spezifikation erneut gelesen, und es sieht so aus, als ob die POD-Typen nicht standardmäßig im Operator 'new []' initialisiert werden. Ich habe die Antwort bearbeitet, um es zu reflektieren, danke. – dasblinkenlight

2

Die Anweisung delete[] weiß nichts darüber, was im Puffer gespeichert ist (einschließlich ob es eine Zeichenfolge ist oder nicht), so dass alle 10 Zeichen gelöscht werden. Ihr strcat-Aufruf überläuft jedoch das Ende des Arrays (da C-Zeichenfolgen ein Nullbyte als Terminator haben), das die Löschung auf Ihrer Plattform möglicherweise unterbrechen und allgemein nicht sicher ist.

3

Die delete[] gibt den Speicher frei, der nach der Zerstörung der Objekte zugewiesen wurde (was nichts für char tut). Es ist nicht wichtig für den Inhalt, d. H. Es werden so viele Objekte freigegeben, wie zugewiesen wurden.

Beachten Sie, dass die Verwendung von strcat() von einem Nullzeichen abhängig ist, um das Ende der Zeichenfolge zu finden, und dass der von new char[n] zurückgegebene Speicher nicht initialisiert ist. Sie wollen mit

*charArray = 0; 

starten von ... und Sie könnten strncat() oder, noch besser, nicht verwenden diese überhaupt, sondern verwenden std::string zu betrachten.

+0

+1 für das Sprechen über (de) Zuweisung anstelle des Löschens (was genauer ist, trotz des Namens des Operators) und Erwähnen von 'std :: string', programmieren Sie C++ doch. :-) – Eric