strcpy wenn dest Puffer ist kleiner als src-Puffer
Ich versuche zu verstehen, der Unterschied/Nachteile von strcpy und strncpy.
Kann jemand bitte helfen:
void main()
{
char src[] = "this is a long string";
char dest[5];
strcpy(dest,src) ;
printf("%s \n", dest);
printf("%s \n", src);
}
Ausgabe:
this is a long string
a long string
FRAGE: ich verstehe nicht, wie die Quelle sting bekam modifiziert. Als pro Erklärung, strcpy halten sollte kopieren, bis es auf ein '\0', so ist es nicht, aber wie kommt es, "src" - string geändert habe.
Bitte erklären.
Dies wird als buffer Overun.
Dieser buffer-overflow-problem veranschaulicht, warum sollten Sie wählen, zu verwenden strncopy über strcpy.
Ich konnte es nicht reproduzieren in Ihren code ein. Ich bekomme
das ist Undefiniertes Verhalten. c-faq.com/ansi/undef.html "undefined: Alles, was überhaupt geschehen kann; die Norm enthält keine Anforderungen. Das Programm kann nicht kompiliert werden, oder es kann falsch ausgeführt (entweder Absturz oder still generieren falsche Ergebnisse), oder es kann zufällig genau das tun, was der Programmierer beabsichtigt hat."
Vielen Dank an alle. Vor allem, weil Sie nicht nur erklärt, die Antwort, aber ging auf, um zu zeigen anschaulich, wie es funktioniert in den Speicher (für das Verhalten angezeigt, in meinem Fall). Auch darauf hingewiesen, dass dies könnte kotzen unterschiedliche Ergebnisse, wie es ist Undefiniertes Verhalten.
Dieser buffer-overflow-problem veranschaulicht, warum sollten Sie wählen, zu verwenden strncopy über strcpy.
Ich konnte es nicht reproduzieren in Ihren code ein. Ich bekomme
tring
im dest-array.das ist Undefiniertes Verhalten. c-faq.com/ansi/undef.html "undefined: Alles, was überhaupt geschehen kann; die Norm enthält keine Anforderungen. Das Programm kann nicht kompiliert werden, oder es kann falsch ausgeführt (entweder Absturz oder still generieren falsche Ergebnisse), oder es kann zufällig genau das tun, was der Programmierer beabsichtigt hat."
Vielen Dank an alle. Vor allem, weil Sie nicht nur erklärt, die Antwort, aber ging auf, um zu zeigen anschaulich, wie es funktioniert in den Speicher (für das Verhalten angezeigt, in meinem Fall). Auch darauf hingewiesen, dass dies könnte kotzen unterschiedliche Ergebnisse, wie es ist Undefiniertes Verhalten.
InformationsquelleAutor user193891 | 2009-10-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die einfache Antwort ist, dass Sie (mit strcpy () - Aufruf) getan, etwas außerhalb der Spezifikationen des Systems, und damit verdientermaßen leiden Undefiniertes Verhalten.
Desto schwieriger wird die Antwort umfasst die Untersuchung der Beton-Speicher-layout auf Ihrem system, und wie strcpy() intern funktioniert. Es geht wahrscheinlich so etwas wie dieses:
Den Buchstaben
D
stehen für die bytes in dest die BuchstabenP
sind padding-bytes, die0
Zeichen sind ASCII-NUL-Zeichen als string-Abschlusszeichen.Nun strcpy(dest,src) ändern Sie die Speicher-Inhalte etwas (vorausgesetzt, dass Sie korrekt behandelt die überlappende Speicherbereiche):
I. e. während dest jetzt "enthält" den vollen string "dies ist eine lange Zeichenfolge" (wenn man das zählen der Speicher übergelaufen), src enthält nun eine völlig andere NUL-terminierten string "a long string".
InformationsquelleAutor ndim
Dies ist ein buffer overflow, und nicht definiertes Verhalten.
In Ihrem Fall scheint es, dass der compiler gesetzt hat
dest
undsrc
sequentiell im Speicher. Beim kopieren vonsrc
zudest
es weiter kopieren über das Ende desdest
und überschreibt Teilsrc
.Und " src " und " dst " angezeigt werden, ausgerichtet auf ein Vielfaches von 4 Zeichen, also mit dest als 5 Zeichen lang, die neuen entstellten src start 8 chars in der original-src (das ist jetzt dest).
Können Sie bitte erklären, die Speicher-Karte, damit wird es einfacher zu verstehen? einfach davon ausgehen, dass alle Speicher startet von Position 1000.. können Sie erklären, die Räume besetzt, dest und src vor und nach der strcpy.
Der Raum besetzt durch dest und src nicht ändern. Die Menge der Platz für Sie reserviert ist konstant. Was sich ändert ist der tatsächliche Inhalt des Speichers. Denn Sie verursacht einen Pufferüberlauf in der Kopie sind Sie nicht einfach nur das ändern der Speicherbereich, der zugewiesen ist, für dest, aber AUCH einige des Speichers, der für src.
Ich habe eine grafische Erklärung zu meiner Antwort unten.
InformationsquelleAutor ephemient
mit hoher likliness der string sind genaue Nachbarn. Also in Ihrem Fall müssen Sie möglicherweise das Bild
dst | | | | |src| | | | | |
damit Sie anfangen zu schreiben und es passiert, dass die Felder von src überschrieben werden.
Allerdings kann man sicherlich nicht auf ihn verlassen. Alles, was passieren könnte, was Sie haben, ist Undefiniertes Verhalten. So etwas sonst noch alles passieren kann auf einem anderen computer einer anderen Zeit und/oder anderen Optionen.
Grüße
Friedrich
InformationsquelleAutor Friedrich
Ihrem code verursacht einen buffer overflow - kopieren dest mehr Zeichen, als es halten kann.
Die zusätzlichen Zeichen geschrieben wurden, auf einer anderen Stelle auf dem stack, in deinem Fall, wo SRK verweist.
Müssen Sie
strncpy()
Funktion.InformationsquelleAutor eyalm
Als zusätzlicher Hinweis bitte beachten Sie, dass
strncpy
Funktion ist nicht die richtige Funktion zu verwenden, wenn Sie benötigen, um führen Sie das kopieren mit der Pufferüberlauf-Schutz. Diese Funktion ist nicht vorgesehen für diesen Zweck, und war nie dafür vorgesehen.strncpy
ist eine Funktion, die erstellt wurde vor langer Zeit um einige sehr anwendungsspezifische Zeichenkette kopieren innerhalb einer ganz bestimmten Dateisystem in einigen alten version von UNIX. Leider, die Autoren der Bibliothek verwaltet zu "highjack" die generischen klingenden Namenstrncpy
für diesen sehr schmalen und spezifischen Zweck. Es wurde dann aus Gründen der Abwärtskompatibilität beibehalten Zwecke. Und jetzt haben wir eine oder zwei Generationen von Programmierern, die machen es Annahmen überstrncpy
's Zweck basiert ausschließlich auf seinen Namen, und somit auch nicht richtig. In Wirklichkeitstrncpy
hat sehr wenig oder keine sinnvollen Anwendungen an alle.C-standard-Bibliothek (zumindest seine C89/90 version) bietet keine string-kopieren-Funktion mit Puffer overrrun Schutz. Um solche geschützten kopieren, müssen Sie entweder einige Plattform-spezifische Funktion, wie strlcpy, strcpy_s oder schreiben Sie selbst einer.
P. S. Diese thread auf StackOverflow enthält eine gute Diskussion über den wirklichen Zweck
strncpy
entwickelt wurde. Sehen Sie diese post speziell für die genaue Erklärung Ihrer Rolle in der UNIX-Datei-system. Auch finden Sie hier für einen guten Artikel, wiestrncpy
gekommen zu sein.Wieder
strncpy
ist eine Funktion für das kopieren eine ganz andere Art von string - string fester Länge. Es ist auch nicht beabsichtigt, verwendet werden, die mit herkömmlichen C-Stil null-terminierte " strings.Morris: ich sehe nicht, was genau Sie versuchen zu erreichen, indem Sie mit
strncpy
es. Die Funktion derstrncpy
ist für Sie wichtig in diesem Fall?Diese Antwort ist so nicht korrekt. Strncpy wird sicherlich nicht überrollt einen Puffer, wenn Sie a) den richtigen Platz für die "String" b) bekommt man es richtig mit der Länge. Für alles, was Sie wahrscheinlich am besten verwenden Sie den folgenden code (pseudo-C, teilweise übernommen von Code Complete II) char buf[MAX_LEN+1]; strncpy(buf, src, MAX_LEN); In diesem Fall strncpy sicherer ist, dann strcpy. Aber du hast Recht, es ist nicht eine Funktion in Standard-C die "buffer overrun protection. Das ist einfach wie C implementiert wurde, speed, speed, speed
Die Antwort ist richtig.
strncpy
macht eine Menge unnütze Arbeit, wenn der string kürzer ist als der Puffer (füllt den Schwanz mit Nullen), und nicht tun, was muss getan werden, wenn der string länger als der Puffer (nicht der terminierenden null). Dies sind die Folgen eines einfachen Tatsache, dassstrncpy
war ursprünglich für einen völlig anderen Zweck. Zwar ist es möglich zu springen, die durch bestimmte Reifen zu machenstrncpy
"Arbeit" hier auch nicht, aber es ist noch nicht das richtige tool für den job. (Sie in Ihrem "pseudocode" vergessen zu initialisieren, die abschließende null.)Ich habe ein P. S. zu meiner Antwort, die enthält einige nützliche links, die einem helfen zu verstehen, den wahren Sinn des
strncpy
Funktion.InformationsquelleAutor AnT
Ich schlage vor, eine schnelle Lesen der:
http://en.wikipedia.org/wiki/Strncpy#strncpy
das zeigt Ihnen die Unterschiede. Im wesentlichen strncpy können Sie angeben, eine Reihe von bytes zu kopieren, was bedeutet, dass die resultierende Zeichenfolge ist nicht unbedingt nullterminated.
Nun, wenn Sie verwenden strcpy zum kopieren einer Zeichenkette über eine andere, nicht überprüft, so dass der resultierende Bereich von Speicher zu sehen, ob es groß genug sind, es nicht halten Sie Ihre hand in dieser Hinsicht. Es prüft bis zum null-Zeichen in den src-string.
Natürlich, dst " in diesem Beispiel ist nur 5 bytes. Also, was passiert? Es hält über das schreiben, an das Ende von dest an und ab an ihm vorbei in den Speicher. Und in diesem Fall den nächsten Teil an Speicher auf dem stack ist Ihre src-string. So, während Ihr den code nicht absichtlich kopieren, das layout von bytes im Speicher, gekoppelt mit dem schreiben über das Ende der Sommerzeit ist der dies verursacht hat.
Hoffe, das hilft!
InformationsquelleAutor Mark Mayo
Entweder bin ich Missverständnis deiner Frage, oder du bist Missverständnis strcpy:
Es klingt für mich wie Sie erwarten strcpy stoppen kopieren in dest, wenn es das andere Ende erreicht, dest, basierend auf dem sehen eine
\0
Charakter. Dies ist nicht, was es tut. strcpy kopiert in das Ziel-bis es erreicht das Ende der Zeichenkette, getrennt durch eine\0
Charakter. Es übernimmt Sie reserviert genug Speicher für die Kopie. Vor dem kopieren der Ziel-Puffer konnte nichts in ihm, einschließlich aller Nullen.strncpy löst dies, indem er Ihnen eigentlich sagen, wie groß der Puffer Sie kopieren in ist, so können Sie vermeiden Fällen, in denen es Kopien mehr als passen kann.
InformationsquelleAutor Herms