Le programme ne tombe pas en panne lors du débordement du tas

J’ai écrit le programme suivant:

#include  #include  #include  void main(int argc, char *argv[]){ char *input; input = (char*)malloc(16); printf("input is : %s\n", input); } 

Quand je lance ceci comme:

 ./test `python -c 'print "A"*5000'` 

ça ne plante pas. Il imprime plutôt des données.

Lorsque j’utilise free(input) après printf , il se bloque.

Pourquoi cela arrive-t-il?

Le code affiché ignore ses arguments en ligne de commande:

 int main(int argc, char *argv[]){ char *input; input = (char*)malloc(16); printf("input is : %s\n", input); } 

Peu importe ce que le script Python fournit. Cependant, votre printf() imprime des données non initialisées; cela conduit à un comportement indéfini. Si printf() ne plante pas et qu’il y a un free(input); appel après la printf() , alors la free() ne devrait pas planter.

Si vous avez manqué une opération de copie et que vous souhaitez afficher quelque chose comme ceci, les règles sont différentes:

 int main(int argc, char *argv[]){ char *input; input = (char*)malloc(16); strcpy(input, argv[1]); printf("input is : %s\n", input); free(input); return 0; } 

Maintenant, vous ne vérifiez pas argv[1] n’est pas un pointeur nul avant de l’utiliser – cela pourrait provoquer un blocage. Et vous piétinez hors des limites de la mémoire allouée si vous transmettez 5 000 caractères dans argv[1] . Quelque chose va probablement déclencher un crash; il n’est pas défini ce qui causera le crash. La strcpy() peut échouer; printf() n’échouera probablement pas si la copie ne fonctionne pas (mais ce n’est pas garanti); free() échouera probablement parce que vous avez piétiné en dehors des limites (mais même cela n’est pas garanti). Telles sont les merveilles d’un «comportement indéfini»; tout peut arriver et c’est un comportement valide.

Pourquoi cela arrive-t-il?

Le débordement de mémoire tampon (dans ce cas, le débordement de tas ) ne provoque pas un crash immédiat. Écrire en dehors des limites de la mémoire allouée provoque un comportement indéfini – tout peut arriver; même cela peut fonctionner correctement.

Existe-t-il un moyen fiable de créer un crash sans avoir free ()

Si vous n’initialisez même pas l’ input pointeur et ne la déréférencez pas (en lecture ou en écriture), vous obtiendrez probablement un SEGFAULT, mais il s’agit toujours d’un comportement «uniquement» indéfini.

À partir du projet de norme C99

Le comportement non défini possible peut aller d’ignorer complètement la situation avec des résultats imprévisibles , de se comporter pendant la traduction ou l’exécution du programme d’une manière documentée caractéristique de l’environnement (avec ou sans émission d’un message de diagnostic), en mettant fin à la traduction ou à l’exécution (avec la publication). d’un message de diagnostic).


Mais sois prudent

Un débordement peut entraîner une corruption des données ou un comportement inattendu de la part de tout processus utilisant la zone mémoire affectée . Sur les systèmes d’exploitation sans protection de la mémoire, il peut s’agir de n’importe quel processus du système .