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 :

pointeur sur matrice de chaine


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Inscrit en
    Mars 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 5
    Par défaut pointeur sur matrice de chaine
    Bonjour,
    à l'exécution de ce programme seuls les deux 1ères chaines apparaissent
    pourquoi ? quel est le problème pourtant les 9 chaines sont allouées ??
    ce qui est plus étonnant c'est que en faisant une boucle for (j=0 ;nomvol[j]!=NULL;j++); le j aura comme valeur 9 ???

    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
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    int main ()
    {
         char **nomvol;
         int i,j;
     
     
         nomvol=(char**)malloc(50*sizeof (char*));
         for (i=0;i<9;i++)
         {
          nomvol[i] = (char*)malloc(50 * sizeof(char));
         scanf("%s",nomvol[i]);
     
         }
         for(j=0;j<9;j++)
         printf(" %s\n",nomvol[j]);
     
         system("pause");
         }

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 505
    Par défaut
    Bonsoir,

    Citation Envoyé par chessop Voir le message
    à l'exécution de ce programme seuls les deux 1ères chaines apparaissent pourquoi ? quel est le problème pourtant les 9 chaines sont allouées ??
    C'est étrange. Le code a l'air correct et fonctionne bien chez moi. Es-tu sûr de saisir des chaînes d'une longueur inférieure à 50 caractères à chaque fois ?

    ce qui est plus étonnant c'est que en faisant une boucle for (j=0 ;nomvol[j]!=NULL;j++); le j aura comme valeur 9 ???
    Ça, par contre, c'est complètement accidentel. L'état de la mémoire allouée par malloc() est complètement indéfini. Si tu as de la chance, la zone allouée était complètement vide (enfin, remplie de zéros). Les neuf premiers pointeurs sont donc forcément initialisés puisqu'ils correspondent aux chaînes que tu as saisies et le suivant est encore vide, donc ton « j » s'arrête au bon endroit, mais rien ne garantit que ce soit toujours le cas.

  3. #3
    Membre régulier
    Inscrit en
    Mars 2010
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Mars 2010
    Messages : 5
    Par défaut
    oui je suis sûr que j'ai saisi les chaines conformes aux conditions !!
    c'est où l'anomalie ??

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 861
    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 861
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par chessop Voir le message
    oui je suis sûr que j'ai saisi les chaines conformes aux conditions !!
    c'est où l'anomalie ??
    Tu sais, le C c'est aussi de la recherche personnelle. T'as essayé de mettre printf("%d: %s", i, nomvol[i]); juste après le scanf ?

    Essaye aussi de remplacer scanf("%s",nomvol[i]); par fgets(nomvol[i], 50, stdin); ou alors aussi remplacer scanf("%s",nomvol[i]); par sprintf(nomvol[i], "essai%d", i);

    Tu compiles et exécutes ce code dans quel environnement ?
    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]

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Ton code fonctionne, j'ai testé. J'ai juste rajouté deux/trois choses (importantes) :

    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
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
     
    int main (void)
    {
    	char ** nomvol = NULL;
    	int i , j ;
     
    	nomvol = malloc( 50 * sizeof (char*) );
    	if ( nomvol != NULL ) /* il FAUT tester la valeur retour */
    	{
    		for ( i = 0 ; i < 50 ; i++) /* il faut initialiser tous les éléments du tableau */
    			nomvol[i] = NULL;
     
    		for ( i = 0 ; i < 9 ; i++)
    		{
    			nomvol[i] = malloc ( 50 * sizeof(char) );
    			if ( nomvol[i] != NULL ) /* il FAUT tester la valeur retour */
    				scanf( "%s" , nomvol[i] );
    		}
     
    		for( j = 0 ; j < 9 ; j++ )
    			if ( nomvol[j] != NULL ) /* on teste avant d'afficher */
    				printf( " %s\n" , nomvol[j] );
    			else
    				printf("-- Erreur --\n");
     
    		for ( i = 0 ; i < 50 ; i++) /* il faut liberer la memoire */
    			free( nomvol[i] );
     
    		free( nomvol ); /* idem */
    		nomvol = NULL ;
    	}
     
    	system("pause");
     
    	return 0;
    }
    Si ça ne fonctionne pas, donne plus d'infos :
    _ ton OS.
    _ ton compilateur.
    _ tes options de compilation.

    c'est que en faisant une boucle for (j=0 ;nomvol[j]!=NULL;j++);
    Ce genre de code est susceptible de faire crasher le programme. Rien ne t'assure que le premier NULL rencontré sera forcément dans les limites du tableau, d'autant que tu n'initialises pas le contenu du tableau. Si ça déborde, ça risque de crasher.

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 861
    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 861
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par jeroman Voir le message
    Ton code fonctionne, j'ai testé. J'ai juste rajouté deux/trois choses (importantes) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for ( i = 0 ; i < 50 ; i++) /* il faut initialiser tous les éléments du tableau */
    	nomvol[i] = NULL;
    Et pourquoi donc ??? C'est une perte de temps puisque 2 lignes en dessous, les éléments sont initialisés avec le résultat du malloc !!!
    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]

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Et pourquoi donc ???
    Pour les mêmes raisons que l'on doit initialiser un pointeur "classique" avec la valeur NULL : c'est sécuritaire, cela permet de savoir si le pointeur pointe sur une zone mémoire valide ou non. Car si sa valeur n'est pas initialisée, comment savoir, une fois qu'on arrive plus loin dans le programme, si elle correspond effectivement bien à une adresse valide ? C'est dangereux de ne pas savoir.
    De plus, lors de la libération de toute la mémoire allouée (c'est beaucoup plus simple de faire une boucle sur la totalité du tableau de pointeurs plutôt que de chercher à savoir quels pointeurs ont été 'malloc'és, sachant qu'un "free(NULL)" n'est pas dangereux), cela évite un crash inutile.

    En effet, si on n'initialise pas les pointeurs du tableau, un code tel que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for ( i = 0 ; i < 50 ; i++)
    			free( nomvol[i] );
    est susceptible de planter.

    Ca va que dans ce code actuel, on sait que seulement 9 pointeurs ont été 'malloc'és, mais dans un programme plus gros, comment peut-on le savoir ?

    Tout initialiser à NULL est, à mon avis, une bonne habitude, sauf si on sait exactement ce que l'on fait. Mais un oubli est si vite arrivé... et cela permet d'éviter des heures de déboggage inutiles.

    C'est une perte de temps puisque 2 lignes en dessous, les éléments sont réinitialisés avec le résultat du malloc !!!
    9 seulement. Les 41 autres pointeurs restants ont une valeur indéterminée.

  8. #8
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par chessop Voir le message
    oui je suis sûr que j'ai saisi les chaines conformes aux conditions !!
    c'est où l'anomalie ??
    Peux-tu fournir un exemple d'éxecution (chaînes saisies et résultat obtenue) ?

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

Discussions similaires

  1. Pointeur sur une chaine de caractère string
    Par Lucier dans le forum C#
    Réponses: 9
    Dernier message: 17/03/2010, 14h22
  2. Pointeur sur le membre d'une matrice
    Par Linu6 dans le forum C
    Réponses: 7
    Dernier message: 13/01/2008, 20h40
  3. Pointeurs sur chaine
    Par hugo1992 dans le forum C
    Réponses: 10
    Dernier message: 28/10/2007, 23h05
  4. [Débutant] Pointeur sur liste chainée
    Par HaTnuX dans le forum C
    Réponses: 2
    Dernier message: 02/12/2006, 17h53
  5. Réponses: 3
    Dernier message: 19/12/2004, 14h30

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