Erreur: Pile autour de la variable "string" a été corrompu
J'ai un petit problème avec le code ci-dessous. C'est un programme simple qui se lit dans les 2 tableaux de char et int. Il stocke ensuite tout le contenu dans une autre chaîne de caractères et l'imprime sur.
#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;
}
Maintenant, le programme est en cours d'exécution fine, mais quand je le ferme, j'obtiens l'erreur suivante:
Moment de l'exécution de l'Échec du contrôle N ° 2 - Pile autour de la variable "string" a été corrompu.
C'est un peu confus et je ne vois pas où est le problème. Je serais reconnaissant pour
tous les conseils.
- Non, mais si vous avez C99 (ou d'une garantie de certaines parties de), vous devez être en utilisant
snprintf
à la place pour éviter ce genre de problème arrive.
Vous devez vous connecter pour publier un commentaire.
Vous écrivez plus de caractères dans 'string' qu'il a de la place allouée pour (plus de 50)
Il y a 37 caractères dans
"Your name is %s %s and you are %d years old."
AVANT d'ajouter les valeurs pour le premier, le dernier et l'âge. Il ne reste que 13 caractères pour les trois variables. Donc, il répand dans l'autre vars a déclaré à l'issue de votre variable "string" sur la pile.Que Jon a mentionné, il est préférable d'utiliser les fonctions qui limite la façon dont beaucoup qu'ils écrivent (le " n " variantes), sinon ceux-ci peuvent être des sources de bufferoverrun exploits.
BTW 'chaîne' est un très mauvais nom pour une variable.
Dehors de toute autre chose, vous avez autorisé pour un nom de 10 caractères au maximum et un nom de 15 caractères maximum. Si ces limites sont atteintes (mais ne pas dépasser) et de l'âge est un nombre à deux chiffres, qui prendra 66 caractères - donc, vous devez déclarer
string
être un tableau de 67 caractères pour faire face (notamment le terminateur null).- Delà de cela, vous devriez être en utilisant des fonctions ou des chaînes de format qui vous permettent de limiter la taille de l'entrée - à l'heure actuelle si quelqu'un entre dans un prénom de plus de 10 caractères (etc), vous allez piétiner sur les autres bits de la mémoire. Il a été un moment depuis que j'ai écrit tout C, mais à l'aide de chaînes de format de "%10s" et "%15s" peut aider à cet égard, ou à l'utilisation
fgets
.De même, je conseille
snprintf
(ousnprintf_s
si il est disponible) au lieu desprintf
pour éviter le dépassement de sortie problème. Utiliser les valeurs de retour de l'ensemble de ces méthodes pour détecter les erreurs, trop 🙂scanf
, mais gracieux de récupération lorsque cette limite est atteinte est inutilement difficile, donc +1 pour recommander d'autres fonctions.Vous pouvez limiter la quantité de caractères scanf lit avec
qui va lire à plus de 9 caractères, puis ajouter un NUL, ce qui est approprié pour un tampon de taille 10.
Je suppose que c'est quelque chose à voir avec le fait que la longueur de la
string
tableau est de 50 caractères, vous avez dans le sprintf 37 (si j'en ai compté droite) plus, puis jusqu'à 11 pourfirst
et un autre 16 pourlast
, en plus de peut-être 2 ou 3 pour l'âge. Qui ajoute jusqu'à plus de 50. Tout fonctionne bien, mais vous aurez très probablement de l'écrasement au-delà de la fin des années 50 caractères alloués. Qui va "travailler", mais endommager la pile, comme vous l'avez observé.