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 :

Problème d'erreur de segmentation


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 4
    Par défaut Problème d'erreur de segmentation
    Bonjour à tous,

    J'essaie de coder en C une fonction qui affiche de manière récursive les "mots" de "aaa....a" à "zzz...zz" (voir un peu plus car j'arrête l'incrémentation des char quand ils arrivent à 127 et non 123) en incrémentant chaque caractère au fur et à mesure.
    Dans le cas où le mot fait 3 caractères, il n'y a pas de soucis mais dès que je passe à 4, l'exécution me sort une erreur de segmentation. Le code me sort bien tous les premiers mots mais arrive à cette erreur de manière variable sur des mots qui commencent généralement pas le caractère 'g'.

    Ci-dessous le code pour le cas où la taille du mot est 4. Est-ce que quelqu'un voit ce qui ne va pas et sur quelle partie de la mémoire je peux avoir cette erreur?

    Question subsidiaire : vous avez surement remarqué dans la fonction main la ligne "bla[taille] = '\0';" Lorsque je ne la mets pas et que j'affiche le mot bla via printf, j'obtiens 4 'a' et un caractère bizarre. Ce caractère disparait lorsque je fixe manuellement la fin du string via "bla[taille] = '\0';" Je ne comprends pas pourquoi j'ai besoin de ça. Une idée?

    Merci à tous pour votre aide et vos réponses et je reste à votre disposition si vous avez besoin d'explications.

    Cordialement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
    #include <stdio.h>
    #include <string.h>
    #define DEBUT_RECH 97
     
    int defileMot(char* motADefiler, int colonne)
    {
    	int tailleMot = strlen(motADefiler);
    	if(colonne >= tailleMot)
    	{
    		printf("erreur colonne\n");
    		return 1;
    	}
    	if(colonne == 0 && motADefiler[colonne] >=127)
    	{
    		printf("fin de la premiere colonne\n");
    		return 0;
    	}
     
    	if(colonne == tailleMot - 1)
    	{
    		if(motADefiler[colonne] >= 127)
    		{	
    			motADefiler[colonne] = DEBUT_RECH;
    			motADefiler[colonne-1]++;
    			defileMot(motADefiler, colonne-1);
    		}
    		else
    		{
    			printf("%s\n", motADefiler);
    			motADefiler[colonne]++;
    			defileMot(motADefiler, colonne);
    		}
    	}
    	else
    	{
    		if(motADefiler[colonne] >= 127)
    		{
    			motADefiler[colonne] = DEBUT_RECH;
    			motADefiler[colonne-1]++;
    			defileMot(motADefiler, colonne-1);
    		}
    		else
    		{
    			defileMot(motADefiler, colonne+1);
    		}
    	}
    	return 2;
    }
     
    int main(void){
     
    	int taille = 4;
    	char bla[taille];
    	for(int i = 0; i < taille; i++)
    	{
    		bla[i] = DEBUT_RECH;
    	}
    	bla[taille] = '\0';
     
    	//printf("%s\n", bla);
    	defileMot(bla, 0);	
    }

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 772
    Par défaut
    Citation Envoyé par vinassefranche Voir le message
    Question subsidiaire : vous avez surement remarqué dans la fonction main la ligne "bla[taille] = '\0';" Lorsque je ne la mets pas et que j'affiche le mot bla via printf, j'obtiens 4 'a' et un caractère bizarre. Ce caractère disparait lorsque je fixe manuellement la fin du string via "bla[taille] = '\0';" Je ne comprends pas pourquoi j'ai besoin de ça. Une idée
    C'est la valeur sentinelle ou butoir si tu préfères.
    Comment crois-tu que la méthode strlen ou printf (avec %s) fonctionne?

    Tant que le caractère vide '\0' n'est pas atteint

    Ton code est trop tordu de toute manière : commence par utiliser memset

    Si tu as une segmentation, je soupçonne que tes histoires de tailleMot [- 1] et colonne [- 1] vont au-delà de 3

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 4
    Par défaut
    Citation Envoyé par foetus Voir le message
    C'est la valeur sentinelle ou butoir si tu préfères.
    Comment crois-tu que la méthode strlen ou printf (avec %s) fonctionne?

    Tant que le caractère vide '\0' n'est pas atteint
    Je comprends bien la nécessité du caractère '\0' mais je ne pensais pas avoir besoin de le rentrer moi-même. Je pensais que la déclaration d'un tableau de char d'une taille donnée créait automatiquement ce caractère à la fin. Si ce n'est pas le cas, ça répond à ma question

    Pour ce qui est des "tailleMot -1" et "colonne -1", au moment où l'erreur apparait, ces variables sont à des valeurs qui ne peuvent pas créer d'erreur, surtout avec un -1 qui aurait tendance à éviter de sortir du tableau. Ca ne vient donc pas de ça.

    Ce qui est surtout bizarre, c'est que le code fonctionne très bien au début. Il me sort bien "aaaa", "aaab", "aaac"..."aaba", "aaca"...."gaaa"... jusqu'à un moment où l'erreur apparait et je ne comprends pas pourquoi.

    Je vais regarder ce que je peux faire avec memset en tout cas. Je sais que mon code est tordu mais ça me dérange de ne pas comprendre pourquoi ça ne marche pas "au bout d'un moment" et je n'ai pas envie de changer de code avant de comprendre

    Merci en tout cas pour ta réponse!

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    À lire ta question subsidiaire, une petite relecture d'un cours sur les chaines de caractères en C s'impose
    En effet une chaine de caractères en C est délimitée par une adresse de départ, et un caractère '\0'. C'est ainsi que les fonctions comme strlen, printf, strcmp... savent où s'arrêter.

    Pour ton erreurs de segmentation, tu as deux problèmes qui y mènent :
    • Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      char bla[taille];
      bla[taille] = '\0';
      Bien que cet ajout est nécessaire, là tu dépasses la taille de ton tableau, il te faudrait rajouter char bla[taille+1];.
    • Ton algorithme effectue un nombre trop important d'appels récursifs, ce qui fait exploser la pile. Je te conseille d'analyser en débogage son parcours, et de revoir sa logique en conséquence.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 4
    Par défaut
    Citation Envoyé par Winjerome Voir le message
    Bonjour,

    À lire ta question subsidiaire, une petite relecture d'un cours sur les chaines de caractères en C s'impose
    En effet une chaine de caractères en C est délimitée par une adresse de départ, et un caractère '\0'. C'est ainsi que les fonctions comme strlen, printf, strcmp... savent où s'arrêter.
    il est vrai que je me remets au C alors que je n'en ai pas fait depuis un bout de temps. Je suis un cours mais apparemment j'essaie d'aller plus vite que là où j'en suis. Comme dit précédemment, je pensais que la déclaration créait ce char de fin... bref!

    Citation Envoyé par Winjerome Voir le message
    [*]Ton algorithme effectue un nombre trop important d'appels récursifs, ce qui fait exploser la pile. Je te conseille d'analyser en débogage son parcours, et de revoir sa logique en conséquence.
    Il s'agit apparemment bien de ce problème. En rajoutant un compteur qui s'incrémente à chaque appel de la fonction et qui diminue à chaque return, le code bugue à 174593, ce qui indique bien un nombre d'appel de la fonction considérablement trop important. Il faut donc que je revoie la logique. Merci beaucoup pour m'avoir mis sur la piste!


    Si jamais vous avez le temps, j'en profite pour poser une question sur le reste de votre réponse :

    Citation Envoyé par Winjerome Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char bla[taille];
    bla[taille] = '\0';
    Bien que cet ajout est nécessaire, là tu dépasses la taille de ton tableau, il te faudrait rajouter char bla[taille+1];.
    D'une, je ne comprends pas le "+1". Tu parles de dépasser la taille du tableau mais en rajoutant 1, j'ai tendance à penser qu'on dépasse encore plus la taille. Ne fallait-il pas lire "-1"?
    Dans ce cas là, j'en déduis qu'il y a deux façons de créer un tableau de char (autre que par les pointers) :
    - bla[4] = {0,0,0,0} : dans ce cas, le compilateur crée lui-même le char '\0' à la fin du tableau
    -
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char bla[5];
    	for(int i = 0; i < 4; i++)
    	{
    		bla[i] = (char) 0;
    	}
    	bla[taille] = '\0';
    Dans ce cas, il faut créer un tableau d'un char plus grand que ce dont on a besoin pour rentrer nous-même le char de fin.

    Est-ce une bêtise ou je résume bien la situation?

    Merci en tout cas encore pour votre réponse claire et utile!

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par vinassefranche Voir le message
    Ne fallait-il pas lire "-1"?
    Surtout pas !
    Toi tu souhaites avoir taille = 4 caractères « utiles » + le caractère '\0' désignant la fin de la chaine, donc un tableau de taille + 1 = 5 caractères au final

    Citation Envoyé par vinassefranche Voir le message
    - bla[4] = {0,0,0,0} : dans ce cas, le compilateur crée lui-même le char '\0' à la fin du tableau
    Là tu as une taille fixe de 4 caractères, qui ne dépend plus de la variable taille, qui plus est de seulement 3 caractères « utiles ». Et ce n'est pas le compilateur seul qui met le '\0', mais bien toi avec la partie droite {0,0,0,0}.
    Citation Envoyé par vinassefranche Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char bla[5];
    	for(int i = 0; i < 4; i++)
    	{
    		bla[i] = (char) 0;
    	}
    	bla[taille] = '\0';
    Ceci pour taille = 4 revient exactement au même que char bla[taille+1];, la dépendance par rapport à la variable taille en moins.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 4
    Par défaut
    Effectivement, j'avais mal lu et je comprends mieux maintenant.
    Tout me parait clair, merci beaucoup et bonne fin de journée!

Discussions similaires

  1. erreur de segmentation , probléme de compilation
    Par henda333 dans le forum C++
    Réponses: 1
    Dernier message: 18/06/2014, 21h19
  2. Problème : erreur de segmentation.
    Par bastnt dans le forum C++
    Réponses: 23
    Dernier message: 05/10/2008, 19h01
  3. [Dev-C++] Erreur de segmentation...
    Par sas dans le forum Dev-C++
    Réponses: 11
    Dernier message: 26/03/2005, 14h25
  4. erreur de segmentation
    Par transistor49 dans le forum C++
    Réponses: 10
    Dernier message: 15/03/2005, 11h18
  5. Problème de déclaration de segment avec use32
    Par le mage tophinus dans le forum Assembleur
    Réponses: 2
    Dernier message: 10/01/2003, 10h17

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