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 sous Linux : Initialisation d'un tableau de chaînes de caractères et son utilisation


Sujet :

C

  1. #1
    Membre actif
    Homme Profil pro
    Dév Java/JavaEE
    Inscrit en
    Décembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dév Java/JavaEE

    Informations forums :
    Inscription : Décembre 2012
    Messages : 53
    Points : 203
    Points
    203
    Par défaut Problème sous Linux : Initialisation d'un tableau de chaînes de caractères et son utilisation
    Bonjour,

    Je ne comprends pas du tout :
    Sous Windows et via Code::Blocks, mon programme en C tourne bien.
    Cependant, dès que je passe sous Linux (Ubuntu, plus précisément), une erreur se produit lors de l'exécution (la compilation étant bonne) :

    "Erreur de segmentation (core dumped)"

    et cela fait des jours que je cherche à la résoudre sans succès.

    Exemple de code posant problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char les_mots[3][6] = { "aaaaaa", "bbbbbb", "cccccc"};
    int j = 0;
    for( j ; j < 3 ; j++)
         printf("%s\n", les_mots[j]);
    Quelqu'un aurait-il une explication/solution ?

    Merci d'avance de votre aide.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 387
    Points : 23 703
    Points
    23 703
    Par défaut
    Lorsque tu passes une chaîne de caractères à une fonction, il faut inclure un terminateur pour que celle-ci sache quand s'arrêter. Pour cela, quand tu utilises les guillemets, le compilateur les termine toutes automatiquement par un '\0' (code ASCII 0). Mais pour que ça marche, il faut prévoir ce caractère supplémentaire.

    Toi, tu définis des tableaux de six caractères et tu passes des chaînes d'exactement six caractères également, si bien que le terminateur passe à la trappe.

    Si ça marche sous Windows, c'est uniquement par accident : si le reste de la mémoire après tes chaînes est à zéro, la fonction interprétera cela comme un terminateur et tu auras l'impression que tout marche bien. Dans le cas contraire, elle continuera jusqu'à rencontrer ce terminateur et si celui-ci ne se présente pas suffisamment tôt, tu risques de sortir du segment mémoire alloué par le système à ton processus, d'où l'erreur de segmentation.

    Essaie avec [3][7] plutôt que [3][6].

  3. #3
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    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 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par siro75 Voir le message
    Bonjour,

    Je ne comprends pas du tout :
    Sous Windows et via Code::Blocks, mon programme en C tourne bien.
    Cependant, dès que je passe sous Linux (Ubuntu, plus précisément), une erreur se produit lors de l'exécution (la compilation étant bonne) :
    Bonjour

    Bienvenue dans le monde du C. Cela te montre 3 choses
    1. le C ne vérifie pas les erreurs éventuelles de l'utilisateur
    2. ce n'est pas parce qu'un programme compile qu'il est correct
    3. ce n'est pas parce qu'un programme s'exécute correctement qu'il n'y a pas une erreur

    Eventuellement cela te montre aussi que Linux est un outil plus fiable pour développer que Windows (parce que dans ton cas tu as la chance qi'il fasse exploser le programme dès qu'il fait un truc interdit sinon tu aurais pu rester longtemps avec cette erreur cachée jusqu'au jour où elle serait reparue au grand jour mais bien trop tard pour que tu la trouves aussi facilement) mais on va m'accuser de parti-pris

    En ce qui concerne les 3 points, c'est donc à toi d'être toujours vigilant surtout quand tu touches aux zones mémoires...
    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]

  4. #4
    Membre actif
    Homme Profil pro
    Dév Java/JavaEE
    Inscrit en
    Décembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dév Java/JavaEE

    Informations forums :
    Inscription : Décembre 2012
    Messages : 53
    Points : 203
    Points
    203
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    Lorsque tu passes une chaîne ...
    Essaie avec [3][7] plutôt que [3][6].
    Bonjour,

    Oui, bien-sûr, j'ai essayé plusieurs choses avant de venir poster mon message ici, y compris la situation dont vous parlez.

    Voici mes essais :

    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
     
    char les_mots[3][7] = { "aaaaaa", "bbbbbb", "cccccc"};
     
    char les_mots[3][7];
    les_mots[0] = "aaaaaa";
    les_mots[1] = "bbbbbb",
    les_mots[2] = "cccccc",
     
    char les_mots[3][7];
    strcpy(les_mots[0], "aaaaaa");
    strcpy(les_mots[1], "bbbbbb");
    strcpy(les_mots[2], "cccccc");
     
    char *les_mots[6] = { "aaaaaa", "bbbbbb", "cccccc"};
     
    char *les_mots[7] = { "aaaaaa", "bbbbbb", "cccccc"};
    char *les_mots[] = { "aaaaaa", "bbbbbb", "cccccc"};
    Je pense que je vais laisser tomber cette implémentation de vouloir proposer un choix de chaînes de caractères via un tableau. Je vais plutôt rajouter dans chacune un numéro qu'il faudra juste choisir et chaque ligne s'effectuera par un simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("n°1 : aaaaaa\n");
    Je récupérerai donc le int que l'utilisateur aura à saisir plutôt qu'une chaîne de caractères.

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    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 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par siro75 Voir le message
    Bonjour,

    Oui, bien-sûr, j'ai essayé plusieurs choses avant de venir poster mon message ici, y compris la situation dont vous parlez.

    Voici mes essais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char les_mots[3][7] = { "aaaaaa", "bbbbbb", "cccccc"};
    Ce code fonctionne. On ne comprend pas pourquoi tu dis qu'il ne fonctionne pas surtout que tu ne dis pas "en quoi" il ne fonctionne pas...
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <stdio.h>
     
    int main()
    {
    	char les_mots[3][7] = { "aaaaaa", "bbbbbb", "cccccc"};
    	int i;
    	for(i=0 ; i < 3 ; i++)
    		printf("%s\n", les_mots[i]);
    }

    Citation Envoyé par siro75 Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char les_mots[3][7];
    les_mots[0] = "aaaaaa";
    les_mots[1] = "bbbbbb",
    les_mots[2] = "cccccc",
    Ceci ne fonctionne pas car tu tentes d'affecter à mot[0] (un char[7] donc une suite de caractères) l'adresse contenant la chaine "aaaaaa". Or on ne met pas une adresse dans un tableau (ou alors dans une case d'un tableau d'adresses)...

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <stdio.h>
     
    int main()
    {
    	char *les_mots[3];
    	les_mots[0]="aaaaaa";
    	les_mots[1]="bbbbbb";
    	les_mots[2]="cccccc";
    	int i;
    	for(i=0 ; i < 3 ; i++)
    		printf("%s\n", les_mots[i]);
    }

    Citation Envoyé par siro75 Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char les_mots[3][7];
    strcpy(les_mots[0], "aaaaaa");
    strcpy(les_mots[1], "bbbbbb");
    strcpy(les_mots[2], "cccccc");
    Je ne vois pas où il y aurait problème
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
    #include <string.h>
     
    int main()
    {
    	char les_mots[3][7];
    	strcpy(les_mots[0], "aaaaaa");
    	strcpy(les_mots[1], "bbbbbb");
    	strcpy(les_mots[2], "cccccc");
    	int i;
    	for(i=0 ; i < 3 ; i++)
    		printf("%s\n", les_mots[i]);
    }

    Citation Envoyé par siro75 Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char *les_mots[6] = { "aaaaaa", "bbbbbb", "cccccc"};
    char *les_mots[7] = { "aaaaaa", "bbbbbb", "cccccc"};
    Oui ça fonctionnera (comme pour mon second exemple). Bon chaque tableau a des adresses inutilisées (mais utilisables ultèrieurement...)

    Citation Envoyé par siro75 Voir le message
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    char *les_mots[] = { "aaaaaa", "bbbbbb", "cccccc"};
    Identique à mon second exemple, le compilo se chargeant de rajouter un "3" entre les crochets.

    Donc en résumé tu dis que tu as fait des essais mais moi j'en doute vu qu'ils fonctionnent (presque) tous...

    Citation Envoyé par siro75 Voir le message
    Je pense que je vais laisser tomber cette implémentation de vouloir proposer un choix de chaînes de caractères via un tableau.
    C'est toi qui voit ; c'est toi que ça concerne...
    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]

  6. #6
    Membre actif
    Homme Profil pro
    Dév Java/JavaEE
    Inscrit en
    Décembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dév Java/JavaEE

    Informations forums :
    Inscription : Décembre 2012
    Messages : 53
    Points : 203
    Points
    203
    Par défaut
    Bonjour,

    Voici la partie de code de mon programme qui me pose effectivement problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int j;
    char les_titres[5][31] = {
    	"Chants_pour_enfants",
            "Opera_italien",
            "Charles_Aznavour,_la_derniere",
            "Cirque_du_Soleil",
            "Danses_africaines"};
     
    for( j; j < 5; j++)
            printf("%s\n", les_titres[j]);
    Ce que j'ai écrit plus haut n'était que des exemples.
    Et je les ai réellement testés mais avec mon vrai code que je montre à présent.
    Avec mon vrai code, ça ne marche pas même si ça respecte la syntaxe des cas qui marchent et que vous validez à juste titre.

    Edit :
    Je viens de comprendre qu'en fait, il y a une grosse différence entre mon code et les exemples que j'ai proposés : dans mon code, les chaînes de caractères ont des tailles différentes et ça change tout concernant l'initialisation du tableau.

    Comment faut-il donc faire ?

  7. #7
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    556
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 556
    Points : 1 428
    Points
    1 428
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    const char * const stringlist[] = {"des chaines","de differentes","tailles"};
    for (unsigned int i = 0 ; i < sizeof(stringlist)/sizeof(stringlist[0]) ; i++)
    {
        printf("%s",stringlist[i]);
    }

  8. #8
    Membre actif
    Homme Profil pro
    Dév Java/JavaEE
    Inscrit en
    Décembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dév Java/JavaEE

    Informations forums :
    Inscription : Décembre 2012
    Messages : 53
    Points : 203
    Points
    203
    Par défaut
    Un grand merci à vous.

  9. #9
    Membre actif
    Homme Profil pro
    Dév Java/JavaEE
    Inscrit en
    Décembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dév Java/JavaEE

    Informations forums :
    Inscription : Décembre 2012
    Messages : 53
    Points : 203
    Points
    203
    Par défaut
    Citation Envoyé par mith06 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for (unsigned int i = 0 ; i < sizeof(stringlist)/sizeof(stringlist[0]) ; i++)
    Bonjour,

    Auriez-vous le temps de me donner des explications sur cette ligne, concernant les sizeof subissant une division apparemment ?
    Je peux recopier du code et le ré-utiliser pour que mon programme fonctionne, mais j'aime bien aussi comprendre.

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    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 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par siro75 Voir le message
    Bonjour,
    Comme dans la vraie vie, un bonjour en début de topic suffit...

    Citation Envoyé par siro75 Voir le message
    Je viens de comprendre qu'en fait, il y a une grosse différence entre mon code et les exemples que j'ai proposés : dans mon code, les chaînes de caractères ont des tailles différentes et ça change tout concernant l'initialisation du tableau.
    Ben voilà. Tu as compris pourquoi nous on ne pouvait pas comprendre ton pb...

    Citation Envoyé par siro75 Voir le message
    Auriez-vous le temps de me donner des explications sur cette ligne, concernant les sizeof subissant une division apparemment ?
    Je peux recopier du code et le ré-utiliser pour que mon programme fonctionne, mais j'aime bien aussi comprendre.
    stringlist est un tableau de n adresses. Chaque adresse faisant p octets (tu remarqueras que je ne me fatigue même pas à essayer de donner une valeur réelle à p parce que c'est inutile tant qu'elle est différente de 0), la taille complète du tableau fera np octets.

    stringlist[0] est la première adresse du tableau. Donc sa taille fait la même taille que tout à l'heure, c'est à dire p octets (toujours p différent de 0).
    Et donc np/p donne n. C'est donc une expression te donnant le nombre d'éléments d'un tableau quand ce nombre est susceptible de changer durant la vie du code...

    Accessoirement quand tu dois gérer un tableau de chaines statiques (invariantes) tu peux effectivement passer par un tableau de pointeurs... mais si tu veux que tes chaines soient modifiables, tu es alors obligé de passer par un tableau de tableaux de caractères (comme ton dernier exemple). Dans ce cas, malheureusement, tu es obligé de prévoir la taille max d'une chaine est d'affecter cette taille à tous les tableaux de caractères.
    Et donc ton dernier exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int j;
    char les_titres[5][30 /* 30 suffit mais si tu veux mettre 31 pas de pb */] = {
    	"Chants_pour_enfants",
            "Opera_italien",
            "Charles_Aznavour,_la_derniere",
            "Cirque_du_Soleil",
            "Danses_africaines"};
     
    for( j=0; j < 5; j++)
            printf("%s\n", les_titres[j]);
    aurait fonctionné pour peu que tu ait intialisé j !!!
    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]

  11. #11
    Membre actif
    Homme Profil pro
    Dév Java/JavaEE
    Inscrit en
    Décembre 2012
    Messages
    53
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dév Java/JavaEE

    Informations forums :
    Inscription : Décembre 2012
    Messages : 53
    Points : 203
    Points
    203
    Par défaut
    Explications détaillées et bien expliquées.
    Merci.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 22/06/2013, 09h38
  2. va_list problème sous linux, pas sous windows
    Par gigiskhan dans le forum C
    Réponses: 11
    Dernier message: 02/10/2012, 17h51
  3. [Eclipse 3.2] Problème sous linux
    Par anonyme13 dans le forum Eclipse Platform
    Réponses: 1
    Dernier message: 22/09/2009, 13h17
  4. [C : system()] Problème sous Linux RH3
    Par Lucinda dans le forum C
    Réponses: 2
    Dernier message: 12/06/2007, 16h54
  5. Tableau de chaînes de caractères
    Par mac1 dans le forum Langage
    Réponses: 3
    Dernier message: 15/01/2006, 13h18

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