J'utilise Eclipse IDE pour les développeurs C / C ++, pendant que j'apprends le C. En théorie, le débordement devrait avoir lieu d'une manière ou d'une autre lorsque je saisis plus grand que la taille de la chaîne que j'attribue. Mais tout va bien et je ne vois pas le problème souhaité.

int main()
{
    char nameArr[15];
    printf("Type name: ");
    scanf("%s",nameArr);
    printf("You are %s.\n",nameArr);

    return(0);
}

Je voulais intentionnellement voir le cas du débordement, mais je ne pouvais pas. Par exemple, lors de l'exécution, si je tape Wolfeschlegelsteinhausenbergerdorff, il sort correctement sans aucun message lié au débordement dans Eclipse. Je ne sais pas si c'est une fonctionnalité de C ou celle d'Eclipse. Est-ce que quelqu'un sait pourquoi il est acceptable de dépasser la taille?

0
candito123 24 sept. 2020 à 03:32

2 réponses

Meilleure réponse

Comme @retiredninja l'a mentionné dans un commentaire, le débordement d'une mémoire tampon entraîne un comportement indéfini, vous ne pouvez donc pas vous attendre à ce que quoi que ce soit se produise ou ne se produise pas.

En disant cela, pour observer un simple débordement de tampon, vous pouvez essayer ceci:

#include <stdio.h>

int main()
{
    char overflow[16];
    char nameArr[16];
    overflow[15] = '\0';
    nameArr[15] = '\0';
    printf("Type name: ");
    scanf("%s" ,nameArr);
    printf("You are %s.\n", nameArr);
    printf("overflow: %s\n", overflow);

    return(0);
}

Quand je compile ceci avec

gcc -Wall -W main.c -o main -fno-stack-protector -O0

Et exécutez-le, je vois

$ ./main
Type name: 123456789abcdefghijklmnopqrstuvwxyz
You are 123456789abcdefghijklmnopqrstuvwxyz.
overflow: hijklmnopqrstuvwxyz

Ce qui montre que le texte supplémentaire est écrit dans la mémoire voisine de la variable voulue. L'ordre compte ici: ces variables vivent sur la pile, qui croît vers le bas à travers la mémoire, donc la mémoire «après» une variable appartient à la variable qui a été déclarée avant elle.

Notez que tout dans ma réponse dépend de l'implémentation, donc on ne peut pas s'attendre à ce qu'il se produise avec tous les compilateurs, systèmes d'exploitation, etc. Ceci est particulièrement vrai parce que nous parlons de comportement non défini.

0
lxop 24 sept. 2020 à 00:53

Cet exemple illustre trop bien pourquoi il est important d'utiliser les outils à votre disposition pour piéger les erreurs de programmation courantes. Un débordement de tableau comme celui-ci peut ne pas être détecté pendant des années, jusqu'à ce que quelqu'un l'utilise comme base d'un exploit. Il est facile de faire des erreurs de ce type - elles ne sont généralement pas aussi évidentes que celle du PO - et elles ne provoquent pas nécessairement un échec lors des tests.

Les compilateurs C modernes offrent une protection contre les situations où un tableau est radié à la fin de la pile. Ils ne peuvent pas faire fonctionner le code fonctionne , mais ils peuvent signaler un échec afin que le défaut puisse être suivi. Par exemple, si je construis le code de l'OP avec gcc en utilisant -fstack-protector, alors même un petit dépassement provoque un échec immédiat:

Type name: 12345678987654321
You are 12345678987654321.
*** stack smashing detected ***: <unknown> terminated

Utilisé en combinaison avec un débogueur, le code du problème est détecté très rapidement.

Si votre compilateur n'offre pas ce genre de vérifications, obtenez un meilleur compilateur;)

1
Kevin Boone 24 sept. 2020 à 06:54