2016-12-20 3 views
-1

Ich habe den folgenden C-Code:Segfault geschieht nicht

#include <stdint.h> 
#include <stdio.h> 

int main(){ 
    uint8_t *array; 
    int i=0; 
    for(;i<32120;i++) 
     printf("Array[%d] = %d \n",i,*(array+i)); 
} 

Da ich für Array den Speicher nicht erklären, würde ich diesen Code erwarten auf der zweiten Iteration segfault, aber es ist nicht der Fall (es geschieht bei i == 3295 auf meine Himbeere und größere zufällige i-Wert auf meinem debian virtuellen Maschine

Fehle ich etwas hier

ps:.? kompiliert mit gcc Version 4.9.2 (Debian 4.9. 2-10)

+5

Undefiniertes Verhalten ist .................. Undefiniert .......... Unvorhersehbar ......... – LPs

+0

_Ich würde dies erwarten Code zu segfault auf der zweiten Iteration _... und warum nicht zum ersten Mal? O_o – LPs

+0

Was ist hier nicht definiert? Der Zugriff auf eine nicht deklarierte Erinnerung? Ist das in der C-Spezifikation geschrieben? –

Antwort

5

Die Segmentierungsfehler treten auf, wenn Sie versuchen, auf nicht ausgelagerten Speicherblock zuzugreifen. Es ist ein undefiniertes Verhalten für den Zugriff auf nicht initialisierte Zeiger, und auch der Zugriff auf Speicher mit nicht initialisierten Index ist undefiniert^2.

Undefiniertes Verhalten kann zu Segmentierungsfehlern führen, kann zu Datenverlust führen, kann dazu führen, dass Papa Noel aus Ihrem Terminal kommt !! oder .... Aber in den meisten Fällen führen speicherbezogene undefinierte Verhaltensprobleme zu Segmentierungsfehlern oder ähnlichen Problemen, aber warum erhalten Sie keinen Segmentierungsfehler, bis Sie den Dereferenzierungsindex erwähnt haben?

Dies liegt daran, dass Sie das Zeiger-Array nicht initialisiert haben. Der im Speicher gespeicherte Wert, den das Array belegt hat, wird nicht geändert. Es ist total durch Ihre Chance, dass diese Variable eine Adresse enthält, die auf den virtuellen Speicher Ihrer Anwendungen ausgelagert wird. Wenn Sie ihn mit Null initialisieren oder statisch machen oder als globale Variable definieren, erhalten Sie definitiv einen Segmentierungsfehler bei der ersten Dereferenzierung.

Einige Beispiele:

Manuelle Initialisierung auf NULL (Null)

{ 
    int * ptr = NULL; 
    int index; 
    *ptr = 1; // segfault 
    *ptr[index] = 1; // may not segfault, based on uninitialized value stored in index 
} 

Statische Variablen

{ 
    static int * ptr; // static variable (default initialized to 0) 
    *ptr = 1; // segfault 
} 

Globale Variablen werden initialisiert automatisch automatisch initialisiert werden, wird auch

int * ptr; // global variable (default initialized to 0) 
{ 
    *ptr = 1; // segfault 
} 

Lokale Speichergrößen im Stapel sind nicht initialisierten und den Wert auf das Gedächtnis behalten unberührt besetzt

{ 
    int * ptr; // unintialized 
    *ptr = 1; // may segfault or may not 
} 
+0

Danke, das macht durchaus Sinn. Dies ist das letzte Mal, dass ich vergessen habe, einen Zeiger zu initialisieren. –

1

Dereferenzierung einen nicht initialisierten Zeiger undefined behavior aufruft. Dies bedeutet, dass alles passieren kann. Das Programm könnte abstürzen, es könnte seltsame Ergebnisse erzeugen oder es könnte richtig funktionieren. Alles hängt davon ab, welcher zufällige Wert zufällig in diesem Zeiger ist.

Es gibt keine Garantie, dass das Aufrufen von undefiniertem Verhalten einen Absturz verursacht.

+0

Also, ob es abstürzt oder nicht ist nicht definiert? –

+0

@PaulOgilvie Korrigieren. Nur weil es nicht unbedingt heißen kann. – dbush

+0

(Ich meine, die Natur von "undefined" ist, dass Sie nicht vorhersagen können, geschweige denn, gurantee, _anything.Natürlich ist das Gegenteil wahr, und so ist Ihre letzte Zeile wahr, obwohl ihr Gegenteil nicht wahr ist, dh es ist ist nicht so, dass ohne ein undefiniertes Verhalten ein _no_ crash garantiert ist. Aber wieder bin ich in der Logik verloren :-) –