2016-05-16 3 views
1

Es ist bekannt, dass eine nicht initialisierte lokale Variable einen unbestimmten Wert hat und durch die Verwendung von undefiniertem Verhalten aufgerufen wird. Aber führen Operationen wie das Kopieren von Fragmenten mit Zeigern und die Überprüfung auf Gleichheit später auch zu undefiniertem Verhalten?Gleichheitsüberprüfung nach dem Kopieren von Fragmenten von int

Das folgende kompiliert und läuft glatt, aber ich bin unsicher.

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    int p; 
    int q = 1; 

    char *_p = (char *)&p; 
    char *_q = (char *)&q; 

    size_t n; 
    for(n = 0; n < sizeof(int); n++) { 
     memcpy(_q++, _p++, sizeof(char)); 
    } 

    if (p == q) { 
     printf("Equal!!!\n"); 
    } 

    return 0; 
} 
+2

Verwenden Sie eine unitäre Variable oder Speicher ist Undefined Behavior. Da Sie aus nicht-entialisiertem Speicher kopieren, sind ja auch alle Operationen, die das Ergebnis dieser Kopie verwenden, Undefiniertes Verhalten. – kaylum

Antwort

1

Sie kopieren nicht initialisierten Speicher über den initialisierten Speicher. Das Endergebnis ist, dass die Inhalte beider Speicherstellen identisch sind und daher übereinstimmen. Da die Quelle nicht initialisiert wurde, kann ihr Wert nicht garantiert werden. Sobald Sie diesen Wert über den zuvor initialisierten Wert kopiert haben, löschen Sie den ursprünglichen Wert und ersetzen ihn durch den unbekannten Wert.

Daher werden sie übereinstimmen.

Obwohl Ihre Kopie Routine ein wenig zu groß ist, ich denke, Sie sich bewusst sind und dessen Verwendung rein für Experimente :)

+1

"Kopieren des initialisierten Speichers über nicht ausgelasteten Speicher". Es ist anders herum. OP kopiert * aus * nicht initialisiertem Speicher. Das ist undefiniertes Verhalten. – kaylum

+0

OOPS! Ja, die Kopie ist genau umgekehrt. Das Ergebnis des Vergleichs wird jedoch nicht undefiniert sein, da beide Integer-Werte (obwohl undefiniert) exakte Kopien voneinander sind und übereinstimmen. – Graeme

+0

Nein, das ist falsch. Der Compiler kann tun, was er will, sobald UB auftritt. Es ist wahrscheinlich, dass die Werte gleich sind, aber es ist immer noch UB, weil es keine Anforderung oder Garantie gibt, dass die Implementierung dieses Ergebnis jedes Mal gibt. – kaylum

0

Um @ Jonathan Follow-up, Sie sind nicht mit undefinierten Verhalten, sondern einen nicht definierten Wert handelt. Der undefinierte Wert wird einfach kopiert.

Was wäre undefiniert, wenn Sie versucht haben, etwas wie dividieren durch einen undefinierten Wert, der Null sein könnte. Oder schlimmer, einen Wert durch einen undefinierten Zeiger zuweisen.

Versuchen Sie die später und Sie können sehr gut Segmentfehler, und wenn Sie nicht tun, sind Sie wahrscheinlich über einige zufällige Speicherposition gehen; oft nicht bemerkt in kleinen, kurzlebigen Programmen, aber ein schreckliches Problem für große, langlebige Programme.

Das Aktivieren von aggressiven Compiler-Prüfungen wird wahrscheinlich die einfachen Fälle erfassen. Die eher obskuren Fälle stellen schwerwiegende Fehler beim Debuggen dar.

Verwandte Themen