2017-06-01 1 views
-3

Der folgende C-Code hat char str [3]; und es soll nur 3 Char richtig speichern?Warum Array kann mehr Daten speichern als es sollte?

Wenn ich jedoch das Programm kompiliere und ausführe, scheint es, dass es mehr als das speichern kann.

Ich bekomme nur den Fehler "Segmentation fault", wenn ich "ABCDEFGHIJKLMNOPQRSTUVWXY" eingegeben habe, was eindeutig mehr als 3 Zeichen ist.

Darf ich wissen warum?

p/s: Ja, ich weiß, "bekommt" -Funktion ist gefährlich und nicht empfohlen zu verwenden. Ich bin nur neugierig, warum es mehr Daten speichern kann, als es sollte.

[email protected]:~/c$ cat -n putsgets.c 
    1 #include <stdio.h> 
    2 
    3 int main() 
    4 { 
    5   char str[3]; 
    6   puts("Enter a line of text: "); 
    7   gets(str); 
    8   puts("\nYou entered: "); 
    9   puts(str); 
    10   return 0; 
    11 } 
[email protected]:~/c$ 
[email protected]:~/c$ gcc putsgets.c -o putsgets 
putsgets.c: In function ‘main’: 
putsgets.c:7:2: warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration] 
    gets(str); 
    ^~~~ 
/tmp/cclFmZp2.o: In function `main': 
putsgets.c:(.text+0x1f): warning: the `gets' function is dangerous and should not be used. 
[email protected]:~/c$ 
[email protected]:~/c$ ./putsgets 
Enter a line of text: 
ABC 

You entered: 
ABC 
[email protected]:~/c$ ./putsgets 
Enter a line of text: 
ABCD  

You entered: 
ABCD 
[email protected]:~/c$ 

Weiter

[email protected]:~/c$ ./putsgets 
Enter a line of text: 
ABCDE  

You entered: 
ABCDE 
[email protected]:~/c$ ./putsgets 
Enter a line of text: 
ABCDE 

You entered: 
ABCDE 
[email protected]:~/c$ ./putsgets 
Enter a line of text: 
ABCDEF 

You entered: 
ABCDEF 

[email protected]:~/c$ ./putsgets 
Enter a line of text: 
ABCDEFGHIJKLMN 

You entered: 
ABCDEFGHIJKLMN 

Schließlich trat Segmentation fault Fehler, wenn ich ABCDEFGHIJKLMNOPQRSTUVWXY (letzte Zeile)

[email protected]:~/c$ ./putsgets 
Enter a line of text: 
ABCDEFGHIJKLMNOPQRSTU 

You entered: 
ABCDEFGHIJKLMNOPQRSTU 
[email protected]:~/c$ ./putsgets 
Enter a line of text: 
ABCDEFGHIJKLMNOPQRSTUVWXYZ 

You entered: 
ABCDEFGHIJKLMNOPQRSTUVWXYZ 
Segmentation fault 
[email protected]:~/c$ ./putsgets 
Enter a line of text: 
ABCDEFGHIJKLMNOPQRSTUVWXY 

You entered: 
ABCDEFGHIJKLMNOPQRSTUVWXY 
Segmentation fault 
[email protected]:~/c$ 
+1

Es ist undefiniertes Verhalten. Es könnte abstürzen oder nicht. –

+0

Das, warum 'wird()' ist nicht mehr im Standard. – Stargateur

Antwort

1

In C können Sie einem Array mehr cbarcters hinzufügen als deklariert, da keine Laufzeitprüfungen durchgeführt werden. Was Sie tun, heißt Pufferüberlauf.

Wenn ein solcher Code Daten über eine Netzwerkverbindung akzeptiert, kann ein Hacker dies zum Ausführen von beliebigem Maschinencode ausnutzen!

Allerdings werden in Java und C# Laufzeitprüfungen durchgeführt und ein Pufferüberlauf verursacht eine OutOfRangeExeption. Diese Überprüfungen werden von der Java Virtual Machine durchgeführt.

Gute Frage und halten Sie Ihre Neugier.

5
eingegeben

Wie Sie wahrscheinlich wissen, ist C nicht für die Speichersicherheit zu überprüfen. Dienstprogramme wie Valgrind können jedoch dabei helfen.

Ihr Betriebssystem gibt Ihrem Programm ein bisschen mehr Speicher, als es angefordert hat, und es findet nur Segmentierungsfehler, wenn Sie einen dieser Speicher verlassen.

How does a segmentation fault work internally (kernel/hardware)?

1

Es ist nicht definiertes Verhalten, weil C und C++ nicht gebunden überprüfen Array.

Verwandte Themen