2016-06-13 19 views
0

Betrachten Sie den folgenden Code ein:
zwei Strings Vergleich

char str1[] = "Hello"; 
char str2[] = "Hello\0\0\0l\0o"; 
int x; 
x=memcmp(str1,str2,sizeof(str2)); 
printf("%d",x); 

Wenn ich es laufen, es zeigt die o/p als:

1 

Können Sie erklären, den Grund für Dies. Ich habe gelernt, dass jedes Byte in beiden Strings verglichen wird und entsprechend zurückkehrt. Aber mir ist nicht klar, was am Ende passiert.

+0

Sind Sie sicher, dass 'str1 []' und 'str2 []' keine Größe haben? –

+0

Hast du darüber nachgedacht, über Memcmp in deinem C-Buch für Anfänger zu lesen? Abgesehen von dem Fehler in Ihrem Code, kann die Antwort auf Ihre Frage dort gefunden werden. – Lundin

Antwort

6

Ihr Programm ruft undefiniertes Verhalten auf.

sizeof(str2) ist größer als sizeof(str1). Wenn Sie das als letztes Argument für memcmp verwenden, greifen Sie auf Speicher zu, den Sie nicht verwenden sollten. Das ist Ursache für undefiniertes Verhalten.

Daher kann die Ausgabe alles sein. Es ist sinnlos, einen Sinn daraus zu machen.

3

Wenn Sie einen Zeichenkettenvergleich durchführen, hört der Vergleich auf, sobald er '\ 0' erreicht. Hier haben Sie eine Memcmp erstellt, die erst nach dem Lesen aller angeforderten Zeichen beendet wird.

In diesem Fall vergleichen Sie die Größe von (Str2) Bytes, die im Fall von str1 wird nach dem implizierten '\ 0' am Ende Müll geben.

Um eine 0 auf dem Vergleich zu erhalten:

  • vergleichen nur sizeof (str1) oder sizeof (str1) +1 Bytes
  • einen String tun vergleichen
1

Denken Sie daran, es ist unsicher und manchmal Gefahr hier memcmp anrufen, weil str1 weniger Länge als str2 hat.

Betrachten Sie den folgenden Code ein:

int main() 
{ 
    char str1[] = "Hello"; 
    char str2[] = "AAAAA\0\0\0l\0o"; 
    for(int i=0; i<sizeof(str2); i++) 
     printf("%02X %02X\n", str1[i], str2[i]); 
    printf("\n%X %X", (int)str1, (int)str2); 
    return 0; 
} 

Der Ausgang ist

48 41 
65 41 
6C 41 
6C 41 
6F 41 
00 00 
41 00 
41 00 
41 6C 
41 00 
41 6F 
00 00 

28FEEE 28FEF4 

können wir das sehen [6] - [11] Bytes str1 ist eigentlich die ersten Bytes von str2, und es könnte durch die Adresse str1 und str2 bestätigt werden. In dem Fall, GCC/MSVC (ich bin nicht sehr sicher über Clang) speichern Sie die beiden String-Const Initializer in einer Zeile. Wenn Sie also memcmp aufrufen, vergleicht die Funktion nach dem Null-Terminator \0 das erste Byte von str2 mit \0. Aber denken Sie daran, die Art und Weise, wie der Compiler die Konstante speichert, kann sich unter allen Umständen ändern. Sie sollten nicht auf dieses Verhalten verlassen.