Wie kann ich "strncat" ohne Puffer-überlauf, betrifft?
Habe ich einen Puffer, ich mache viel "strncat". Ich möchte sicherstellen, dass ich nie überlauf der buffer-Größe.
char buff[64];
strcpy(buff, "String 1");
strncat(buff, "String 2", sizeof(buff));
strncat(buff, "String 3", sizeof(buff));
Statt sizeof(buff), ich möchte sagen, etwas buff - xxx. Ich möchte sicherstellen, dass ich nie überschreiben des Puffers
InformationsquelleAutor jscode | 2011-08-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
Berücksichtigen, die Größe des vorhandenen string und dem null-terminator
strncpy nicht. Wenn die Zahl erreicht ist, bevor der gesamte string src kopiert wurde, wird das resultierende Zeichen-array ist nicht null-terminiert ist. Aber für dieses spezielle Beispiel, wo BUFFER_SIZE=64 und "String 1" ist kürzer, du hast Recht, es ist nicht mehr benötigte, weil strncpy wird, kopieren Sie auch die null: en.cppreference.com/w/cpp/string/byte/strncpy
InformationsquelleAutor Joe
Warum nicht
snprintf
? Im Gegensatz zustrncat
es erwartet die Größe des Puffers, aber noch wichtiger ist, es gibt keine versteckten O(n).Strcat finden muss, um den null-terminator auf jede Zeichenfolge verkettet, und jedes mal führen Sie durch den gesamten Puffer um das Ende zu finden. Jedes mal, wenn der string länger wird, strcat verlangsamt. Sprintf, auf der anderen Seite kann verfolgen, das Ende. Sie werden feststellen, dass
Ist Häufig schneller und besser lesbare Lösung.
Wenn Sie nicht warten können,
snprintf
gibt die Anzahl der Zeichen geschrieben, so können Sie speichern die Puffer-offset, so dassoffset+=snprintf(buf+offset, (sizeof buf)-offset, "%s", "String2")
Es gibt Stärke in dieser Antwort. strcat ist eine implizite Suche nach der NULL-terminator.
InformationsquelleAutor Dave
Die Art und Weise Sie die
strncat
Funktion in der orignal code wäre eigentlich angemessen für eine andere Funktion:strlcat
(Hinweis:l
stattn
). Diestrlcat
Funktion ist nicht standard, aber es ist eine beliebte Umsetzung-vorausgesetzt, Ersatz fürstrncat
.strlcat
erwartet, dass die gesamte Größe des gesamten Ziel-Puffer als Ihr letztes argument.Mittlerweile
strncat
erwartet, dass die Größe der übrigen ungenutzten Teils des Ziel-Puffer, wie das Dritte argument. Aus diesem Grund, wird Ihr ursprünglicher code ist falsch.Ich würde vorschlagen, dass anstatt das zu tun, was schreckliche Missbrauch von
strncpy
und eindeutige Scans mit denenstrlen
Anrufe (beides Probleme, die in Joe ' s Antwort), Sie verwenden entweder eine Umsetzung-sofernstrlcat
oder implementieren selbst einer (wenn Ihre Implementierung bietet keinestrlcat
).http://en.wikipedia.org/wiki/Strlcpy
InformationsquelleAutor AnT
Dies ist der beste Weg, es zu tun.
sizeof()
nur gibt Ihnen die Größe der Zeiger auf die Daten, wenn Sie nicht reservieren, es lokal (du hast reservieren, lokal ist in diesem Fall aber besser, es zu tun auf diese Weise, und es wird funktionieren, wenn Sie den code wieder mit eingerechnet).sizeof
wird ihm die Größe des gesamten Puffers, da es ein array, und nicht einen dynamisch zugewiesenen Speicherblock, der.Nicht wahr. Wenn
sizeof
angewendet wird, um ein array-Objekt, es wertet die Gesamt Größe des array-Objekts. Es gibt kein "Zeiger auf die Daten" jeglicher Art in den OP-code.Ich mag, dass ich habe unten gestimmt und akzeptiert die Antwort, die gestohlen wurde von mir, seit es gepostet wurde, mindestens eine minute nach.
stimmt, die Punkte für einen lokalen Puffer -- ich geändert, um zu zeigen, meine wahre Punkt. Wenn er wieder einkalkuliert zugeordnet werden, gäbe es hässliche bugs.
siehe oben Kommentar -- ich kann nicht benachrichtigt 2 Leute, die es scheint.
InformationsquelleAutor Hogan
Hogan hat die Frage beantwortet sufficently; allerdings, wenn Sie besorgt sind über Pufferüberläufe in
strcat(...)
Sie sollten gleichermaßen besorgt über buffer overflows in alle anderen string-Funktionen.Verwenden
strnlen(...)
undstrncpy(...)
wirklich sicher, dass Sie bleiben in Ihrem Puffer. Wenn Sie nicht über einestrnlen(...)
Funktion, es zu schreiben.strnlen
undstrncpy
sind Funktionen, die die Arbeit mit fester Breite Zeichenfolgen. Sie haben nichts zu tun mit "null-terminierte" strings. Mittlerweile, der OP interessiert sich null-terminierte Zeichenfolgen, die speziell, wie folgt aus der Frage. Es ist wahr, dass kann man oft sehenstrncpy
missbraucht withr null-terminierte Zeichenfolgen, alles in Ordnung. Aber was iststrnlen
hier tun, ist völlig unklar für mich.Generell ist die Behandlung von null-terminierte " strings als möglicherweise gebunden an einen string fester Länge ist, was verhindert, dass ein buffer overflow. Wenn man sich auf die null-Terminierung (mit der nicht-n-Funktion), verlassen Sie sich auf den null-terminator wird nur so weit vom Anfang der Zeichenkette, das ist ein Rezept für evtl. überlaufende Puffer kopieren (wenn die Annahme über das null-Endzeichen nicht halten).
InformationsquelleAutor Edwin Buck