9
votes

Erreur: Stack autour de la variable 'String' a été corrompue

J'ai un petit problème avec le code ci-dessous. C'est un programme simple qui lit en 2 tableaux de Char et d'Int. Ensuite, il stocke tout le contenu dans une autre chaîne et l'imprime.

#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;
}

c

1 commentaires

Non liée, mais si vous avez C99 (ou une garantie de certaines parties), vous devriez utiliser snaprintf plutôt pour empêcher ce type de problème de se produire.


4 Réponses :


17
votes

Vous écrivez plus de caractères dans 'String' qu'il a de la place allouée pour (c'est-à-dire plus de 50)

Il y a 37 caractères dans "Votre nom est% s% s et vous êtes% d ans." Avant d'ajouter les valeurs pour le premier, dernier et âge. Cela ne fait que 13 caractères pour les trois variables. Donc, il se répand dans les autres vars déclaré après votre variable 'String' sur la pile.

Comme Jon mentionné, il est préférable d'utiliser les fonctions qui limitent la quantité d'écriture (n 'variantes), sinon elles peuvent être des sources d'exploits de BufferOverrun.

BTW 'String' est un nom très médiocre pour une variable.


0 commentaires

1
votes

Je suppose que c'est quelque chose à faire avec le fait que la longueur de la chaîne est de 50 caractères, vous avez dans le sprintf 37 (si je compte à droite) plus jusqu'à 11 pour premier et un autre 16 pour Dernier , plus 2 ou 3 pour l'âge. Cela ajoute à plus de 50 ans. Tout fonctionne bien, mais vous écrivez très probablement au-delà de la fin des 50 caractères alloués. Cela va «travailler», mais corrompre la pile, comme vous l'avez observé.


0 commentaires

4
votes

Outre tout autre chose, vous avez autorisé un prénom de 10 caractères maximum et un nom de famille de 15 caractères maximum. Si ces limites sont atteintes (mais non dépassées) et que l'âge est un numéro à deux chiffres, cela prendra 66 caractères - vous devrez donc déclarer string pour être un tableau de 67 caractères pour faire face (à inclure le terminateur NULL).

Au-delà de cela, vous devez utiliser des fonctions ou des chaînes de format qui vous permettent de limiter la taille de l'entrée - actuellement si une personne entre un prénom de plus de 10 caractères (etc.), vous écraserez d'autres bits de mémoire. Cela fait longtemps que j'ai écrit des C, mais à l'aide de chaînes de format de "% 10s" et "% 15s" peut aider à cet égard - ou utiliser fgets . .

De même, je suggérerais d'utiliser snaprintf (ou snprintf_s s'il est disponible pour vous) au lieu de sprintf pour éviter le problème de la sortie de dépassement . Utilisez les valeurs de retour de toutes ces méthodes pour détecter des erreurs aussi :)


1 commentaires

Vous pouvez limiter la taille avec scanf , mais la récupération gracieuse lorsque ladite limite est atteinte est inutilement difficile, de +1 pour recommander d'autres fonctions.



2
votes

Vous pouvez limiter la quantité de caractères numériques lit avec xxx

qui lira au plus 9 caractères, puis appendez un nul, qui convient à un tampon de taille 10.


0 commentaires