2011-01-10 5 views
5

Ich habe ein kleines Problem mit dem Code unten. Es ist ein einfaches Programm, das 2 Arrays von char und ein int einliest. Dann speichert es den gesamten Inhalt in einer anderen Zeichenfolge und druckt es aus.Fehler: Stack um die Variable 'String' wurde beschädigt

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

int main() 

{ 
    char string [50]; 
    char first [11]; 
    char last [16]; 
    int age = 0; 


    printf("Please type in your first name: "); 
     scanf("%s", first); 

    printf("Please type in your last name: "); 
     scanf("%s", last); 

    printf("Please type in your age: "); 
     scanf("%d", &age); 

    sprintf(string, "Your name is %s %s and you are %d years old.", first, last, age); 
     puts(string); 

    getchar(); 
    getchar(); 

    return 0; 
} 

Jetzt wird das Programm läuft gut, aber wenn ich es schließen, erhalte ich folgende Fehlermeldung: Run-Time Check Failure # 2 - Stapeln Sie rund um die Variable 'string' beschädigt wurde. Das ist ein bisschen verwirrend und ich kann nicht herausfinden, wo das Problem liegt. Ich wäre dankbar für einen Rat.

+1

Nicht verwandt, aber wenn Sie C99 haben (oder eine Garantie für einige Teile davon), sollten Sie stattdessen "snprintf" verwenden, um diese Art von Problem zu verhindern. –

Antwort

13

Sie sind mehr Zeichen in ‚string‘ zu schreiben, als es Raum für zugewiesen hat (das heißt mehr als 50)

Es gibt 37 Zeichen in "Your name is %s %s and you are %d years old." bevor Sie die Werte für den ersten hinzufügen, letzte und Alter. Das lässt nur 13 Zeichen für alle drei Variablen übrig. Es fließt also in die anderen Variablen, die nach der Variablen 'string' auf dem Stapel deklariert sind.

Wie Jon bereits erwähnt hat, ist es die beste Vorgehensweise, die Funktionen zu verwenden, die die Schreibtiefe einschränken (die 'n' Varianten), sonst können diese Quellen für Pufferüberlauf-Exploits sein.

BTW 'Zeichenfolge' ist ein sehr schlechter Name für eine Variable.

1

Ich würde vermuten, es ist etwas mit der Tatsache zu tun, dass die Länge des string Array 50 Zeichen sind, können Sie in der sprintf haben 37 (wenn ich richtig gezählt) und dann für first und andere bis zu 11 16 für last , plus vielleicht 2 oder 3 für das Alter. Das ergibt mehr als 50. Alles funktioniert gut, aber Sie werden sehr wahrscheinlich über das Ende der 50 Zeichen hinaus überschreiben. Das wird "funktionieren", aber den Stack korrumpieren, wie Sie beobachtet haben.

4

Abgesehen von allem anderen haben Sie einen Vornamen mit bis zu 10 Zeichen und einen Nachnamen mit bis zu 15 Zeichen erlaubt. Wenn diese Grenzen erreicht (aber nicht überschritten) werden und das Alter eine zweistellige Zahl ist, dauert das 66 Zeichen - Sie müssten also string zu einem Array von 67 Zeichen erklären (um den Nullabschluss zu enthalten).

Darüber hinaus sollten Sie Funktionen oder Formatzeichenfolgen verwenden, mit denen Sie die Größe der Eingabe begrenzen können. Wenn jemand einen Vornamen von mehr als 10 Zeichen (etc) eingibt, werden andere Speicherbereiche übersteuert . Es ist eine Weile her, seit ich irgendein C geschrieben habe, aber die Verwendung von Formatzeichenfolgen wie "% 10s" und "% 15s" kann dabei helfen - oder fgets verwenden.

Ebenso würde ich vorschlagen, snprintf (oder snprintf_s, wenn es für Sie verfügbar ist) anstelle von sprintf, um das Überlauf-Ausgabe-Problem zu vermeiden. Verwenden Sie die Rückgabewerte aller dieser Methoden, Fehler zu erkennen, auch :)

+0

Sie können die Größe mit 'scanf' begrenzen, aber eine grazile Wiederherstellung, wenn das Limit erreicht ist, ist unnötig schwer, also +1 für die Empfehlung anderer Funktionen. –

2

Sie können die Menge der Zeichen begrenzen scanf liest mit

scanf("%9s", foo) 

die höchstens 9 Zeichen gelesen wird, dann fügen Sie ein NUL, Das ist für einen Puffer der Größe 10 geeignet.

Verwandte Themen