IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

pourquoi j'ai une segmentation fault


Sujet :

C

  1. #21
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Donc; si j'ai bien lu ce que tu as écrit tu ajoutes +1 à la taille du tampon à fgets et cela fonctionnera / fonctionne sans UB ?

    Vue d'ici et je dois encore être, le seul de nous deux à remarquer tes ambiguïtés de taille tampon, car avec un +1 à size_buff en a un très beau; ... mais très beau UB.Aussi je dois probablement être le seul de nous deux a comprendre qu'il ne faut pas indexer un buffer au-delà de sa taille ?

    [COLOR=#51545B]Au début mon tout premier post je parlais d'avoir un garde-fou pour éviter un débordement ou pire UB en quoi ton UB pourrais également évité un off by one ?
    J'ai l'impression qu'il y a ici confusion entre longueur de chaîne (caractère nul terminal non compris) et taille de buffer (caractère nul compris).
    • strlen() retourne une longueur de chaîne.
    • fgets() accepte une taille de buffer.


    Personnellement, j'adopte une nomenclature stricte pour ça, en distinguant bien xxxLength de xxxSize. Le code devrait donc être corrigé en:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main(void) {
     
        char buff[] = "babidy";
        size_t length_buff = strlen(buff);
     
        (void)fgets(buff, length_buff + 1, stdin);
        return EXIT_SUCCESS;
    }

    Voire, si on veut être aussi explicite que possible:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int main(void) {
     
        char buff[] = "babidy";
        size_t length_buff = strlen(buff);
        size_t size_buff = length_buff + 1;
     
        (void)fgets(buff, size_buff, stdin);
        return EXIT_SUCCESS;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  2. #22
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    @Sve@r: Pour le coup du (void), ce n'est pas la première fois que je vois ça, et le composant qu'il te manque pour comprendre, c'est le composant compilo/analyseur statique.
    Oui effectivement je ne connais rien concernant cet outil. De mon côté j'en suis resté au très basique "gcc" sous Linux (ma toolchain à moi c'est le Makefile). Et même en mettant des options style -Wall -Werror -O2 ça ne dit rien sur l'oubli du check des fonctions.
    J'ai même tenté un splint sur un classique...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include <stdio.h>
     
    int main() {
    	(void)printf("Hello\n");
    	return 0;
    }
    ...et avec ou sans le cast, rien concernant printf. Mais au-moins tu as expliqué le pourquoi du comment

    PS concernant split rien concernant printf mais il me casse les c... sur l'oubli des paramètres du main() et quand je les rajoute, il me les rebrise sur le fait que argc n'est pas utilisé

    Citation Envoyé par sambia39 Voir le message
    ton fgets est sans UB; même écrit comme ceci: : (void)fgets(buff, size_buff + 1, stdin) avec un char buff[]=""
    Oui, même ainsi. size_buf vaut 0 et je passe 1 à fgets() qui bloque à 0 afin de se réserver une place pour le '\0' qui ira dans buff taillé à 1, pas de UB.

    Citation Envoyé par sambia39 Voir le message
    Vue d'ici et je dois encore être, le seul de nous deux à remarquer tes ambiguïtés de taille tampon, car avec un +1 à size_buff en a un très beau; ... mais très beau UB.Aussi je dois probablement être le seul de nous deux a comprendre qu'il ne faut pas indexer un buffer au-delà de sa taille ?
    Oui, et t'es même probablement le seul d'entre nous tous.
    Quand tu écris char buff[] = "babidy" tu as buff qui est taillé à 7 caractères {'b', 'a', 'b', 'y', 'd', 'y', '\0'}. Or size_buff vaut 6 (le nb de caractères situés avant le '\0'). Donc quand j'écris fgets(buff, size_buff+1, stdin) j'écris en réalité fgets(buff, 7, stdin). Voilà. buff taillé à 7 et 7 demandés dans fgets(), je ne vois pas en quoi je suis au delà de la taille autorisée. "très beau;... mais très beau UB". Pfff.

    Citation Envoyé par sambia39 Voir le message
    Citation Envoyé par sambia39 Voir le message
    et je dois encore être, le seul de nous deux à remarquer tes ambiguïtés de taille tampon
    tu ajoutes +1 à la taille du tampon
    C'est toi qui me parle de "mes" ambiguïtés de taille tampon??? Toi qui ne sait même pas que strlen() ne donne pas la taille du tampon mais (au mieux) la taille du tampon - 1???

    Citation Envoyé par sambia39 Voir le message
    à fgets et cela fonctionnera / fonctionne sans UB ?
    Oui j'ajoute +1 à ton strlen() car d'une part ton strlen() renvoie la taille allouée à size_buf - 1 (en admettant que tu n'aies évidemment pas écrit char buf[50]="babidy" comme dans ton exemple d'hier) et d'autre part fgets() retranche systématiquement 1 à la valeur qu'on lui donne pour garantir l'espace pour stocker le '\0'. Donc +1 d'un côté, -1 de l'autre = Zéro UB.

    Citation Envoyé par sambia39 Voir le message
    Au début mon tout premier post je parlais d'avoir un garde-fou pour éviter un débordement ou pire UB
    Ben t'as qu'à utiliser les macros pour tailler ta zone au lieu de mettre du char pour passer par strlen(). Je veux faire saisir (on va dire un nom) j'écris

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define SZ_NOM               (10)
    char nom[SZ_NOM + 1];
    fgets(nom, SZ_NOM + 1, stdin)
    Et je n'ai pas besoin de garde fou pour savoir que ça fonctionnera dans tous les contextes, y compris si on écrit char nom[SZ_NOM+1]="" ou même si on écrit (???) #define SZ_NOM (0). Mais "fonctionner" n'est pas synonyme de "produira le résultat attendu". Il est évident que dans ce dernier cas, je ne pourrai jamais faire saisir un nom mais dans tous les cas, y compris ce dernier, ce code n'aura pas de UB sur le remplissage du tableau au delà de sa taille.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #23
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 431
    Points : 43 057
    Points
    43 057
    Par défaut
    Les gars, vous croyez que le demandeur a compris quelque chose à votre crepage de chignon ?
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Pourquoi ce code plante (segmentation fault)
    Par fcjunic dans le forum Débuter
    Réponses: 3
    Dernier message: 19/01/2011, 12h05
  2. free() qui provoque une segmentation fault
    Par bringer dans le forum Débuter
    Réponses: 16
    Dernier message: 19/11/2010, 17h46
  3. pourquoi 'segmentation fault'?
    Par thepinguin dans le forum C
    Réponses: 25
    Dernier message: 21/11/2006, 22h23
  4. Segmentation fault : pourquoi ?
    Par Dan_coyle dans le forum C
    Réponses: 5
    Dernier message: 23/04/2006, 20h26
  5. Réponses: 6
    Dernier message: 13/11/2005, 12h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo