2017-01-25 3 views
0

Von der C Standard:Was ist die Überlappung von Saiten nach dem C-Standard?

7.21.2.4 Die Strncpy Funktion

Wenn das Kopieren zwischen Objekten erfolgt, die sich überlappen, ist das Verhalten nicht definiert.


Was überlappt?

Es ist klar, dass es überlappt, wenn der Anfang der Zielzeichenfolge das Ende der Quellenzeichenfolge kreuzt.

Aber überlappt sich im nächsten Beispiel?

const char* dateConst = "2017-01-25"; 
char* date = malloc(16); 
strcpy(date, dateConst); 

strncpy(date+4, date+5, 2); 
strncpy(date+6, date+8, 3); 

printf("%s\n", date); 

Ausgang: 20170125

Wenn Strncpy nur Symbole char von char copyes wie es in this implementation ist, sollte es kein Problem sein.

+1

Während es der C-Standard ist diktiert das Verhalten von 'strncpy', scheinen Sie C++ zu kompilieren. – StoryTeller

+0

' strncpy' ist eine gefährliche Funktion und sollte vermieden werden. Es war nie beabsichtigt, mit Null-terminierten Strings zu beginnen. Verwenden Sie stattdessen 'memcpy' oder' strcpy'. – Lundin

Antwort

1

Wenn strncpy kopiert nur Symbole char von char wie es in dieser Implementierung ist, sollte es kein Problem geben.

Das ist genau das Problem. Der Standard gibt nicht an, auf welche Weise die Funktion arbeiten muss, sondern welche Ausgabe geben soll, und gibt gleichzeitig an, ob bei einer Überlappung das Ergebnis UB ist mögen .

Dies liegt daran, dass neue Anweisungen oder Prozessorarchitekturen die Verwendung neuer und effizienterer Anweisungen unterstützen könnten, die einem anderen Adressierungsweg folgen könnten (d. H. In umgekehrter Reihenfolge oder in gemischter Reihenfolge kopieren). Dies könnte zu einem Ergebnis führen, das nicht vorhersehbar ist, nämlich undefiniertes Verhalten.

Schließlich können Sie memmove Funktion verwenden, die explizit Überschneidungen erlaubt, oder schreiben Sie Ihre eigene Funktion, die Überlappung bewusst ist.

1

strncpy muss nicht auf eine bestimmte Art und Weise implementiert werden. Der C-Standard diktiert nur den API-Vertrag, dem er folgen sollte. Jede spezifische Implementierung kann sich dafür entscheiden, die Überschneidung zu einem Nicht-Problem zu machen, aber sie wird vom Standard nicht dazu gezwungen.

strncpy kann in Bezug auf memcpy implementiert werden, die bei der Überlappung von Quelle und Ziel einem undefinierten Verhalten unterliegt. Aber mit der oben genannten Spezifikation ist es vollkommen in Ordnung.

+0

'memcpy' akzeptiert keine Überlappung,' memove' erlaubt Überlappungen. Vielleicht möchten Sie die Antwort beheben. –

+0

@Frankie_C - Ich weiß nicht, seit ich meinte, was ich sagte und sagte, was ich meinte. 'strncpy' kann im Falle einer Überlappung ein undefiniertes Verhalten haben, so dass ** **' 'memcpy' '(in einer möglichen Bibliotheksimplementierung) verwendet werden kann und dem Benutzer die Schuld geben kann, wenn sich die Dinge überschneiden. – StoryTeller

+0

Sorry, ich habe mich missverstanden. Wenn Sie einverstanden sind, werde ich alle Kommentare entfernen. –

Verwandte Themen