4 Stimmen

Beim Kopieren von Zeichenketten in C Platz für das abschließende Null-Zeichen zuweisen?

Const char* src = "hallo";

Aufruf von strlen(src); gibt Größe 5 zurück...

Sagen wir, ich mache das:

char* dest = new char[strlen(src)];
strcpy(dest, src);

Das sieht nicht so aus, als ob es funktionieren sollte, aber wenn ich alles ausgeben lasse, sieht es richtig aus. Es scheint, als würde ich keinen Platz für den Nullterminator am Ende reservieren... ist das richtig? Danke

15voto

Greg Hewgill Punkte 882617

Sie haben Recht, dass Sie keinen Platz für den Terminator zuweisen, jedoch Wenn Sie dies nicht tun, wird Ihr Programm nicht unbedingt scheitern. Möglicherweise überschreiben Sie die folgenden Informationen auf dem Heap, oder Ihr Heap-Manager rundet die Zuweisungsgröße auf ein Vielfaches von 16 Byte oder ähnliches auf, so dass Sie nicht unbedingt eine sichtbare Auswirkung dieses Fehlers sehen werden.

Wenn Sie Ihr Programm unter Valgrind oder einen anderen Heap-Debugger verwenden, können Sie dieses Problem möglicherweise früher erkennen.

11voto

Juliano Punkte 35709

Ja, Sie sollten mindestens strlen(src)+1 Zeichen zuweisen.

7voto

Chris Lutz Punkte 69879

Das sieht nicht so aus, als ob es funktionieren sollte, aber wenn ich alles ausgeben lasse, sieht es richtig aus.

Willkommen in der Welt von Undefined Behavior. Wenn Sie dies tun, kann alles Mögliche passieren. Ihr Programm kann abstürzen, Ihr Computer kann abstürzen, Ihr Computer kann explodieren, Dämonen können aus der Nase fliegen .

Und das Schlimmste ist, dass Ihr Programm gut läuft und unauffällig aussieht, als würde es korrekt arbeiten, bis es eines Tages anfängt, Müll auszuspucken, weil es irgendwo sensible Daten überschreibt, weil irgendwo jemand ein Zeichen zu wenig für seine Arrays zugewiesen hat, und jetzt haben Sie den Heap beschädigt und bekommen einen Segfault an einem Punkt, der eine Million Meilen entfernt ist, oder noch schlimmer, Ihr Programm tuckert fröhlich mit einem beschädigten Heap weiter und Ihre Funktionen arbeiten mit beschädigten Kreditkartennummern und Sie bekommen großen Ärger.

Auch wenn es so aussieht, als ob es funktioniert, tut es das nicht. Das ist Undefined Behavior. Vermeiden Sie es, denn Sie können nie sicher sein, was es tun wird, und selbst wenn das, was es tut, wenn Sie es ausprobieren, in Ordnung ist, kann es auf einer anderen Plattform nicht in Ordnung sein.

3voto

Martin York Punkte 245363

Die beste Beschreibung, die ich gelesen habe (war auf stackoverflow) und ging wie folgt:

Wenn die Höchstgeschwindigkeit 50 beträgt und Sie 60 fahren. Vielleicht haben Sie Glück und bekommen keinen Strafzettel, aber eines Tages, vielleicht nicht heute, vielleicht nicht morgen, aber eines Tages wird der Polizist auf Sie warten. An diesem Tag werden Sie bezahlen, und zwar teuer.

Wenn jemand das Original finden kann, würde ich lieber darauf hinweisen, dass sie viel eloquenter waren als meine Erklärung.

2voto

Brian R. Bondy Punkte 325712

strcpy kopiert das null-terminierte Zeichen ebenso wie alle anderen Zeichen.

Sie kopieren also die Länge von hello + 1, also 6, in eine Puffergröße von 5.

Sie haben hier jedoch einen Pufferüberlauf, und das Überschreiben von Speicher, der nicht Ihr eigener ist, führt zu undefinierten Ergebnissen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X