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 lors de l'assignation d'une matrice de string avec strcpy


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Inscrit en
    Février 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 4
    Par défaut problème lors de l'assignation d'une matrice de string avec strcpy
    bonjour,

    j'ai un problème pas évident: j'ai une structure qui contient une matrice de string.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct plateau2d plateau2d;
    struct plateau2d
    {
        int taille_carre;
        int largeur;
        int hauteur;
        char*** plateau;
    };
    l'allocation en memoire fonctionne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    jeu.plateau= (char***) malloc(sizeof(char**) * nbr_carre_largeur );
        for (i=0; i < nbr_carre_largeur ;i++)
    		jeu.plateau[i] = (char**) malloc(sizeof(char[TAILLE_MAX]) * nbr_carre_hauteur);
    et l'initialisation de cette matrice fonctionne aussi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void init_plateau ( plateau2d jeu )
    {
        int i,j;
        for(i=0;i < jeu.largeur ; i++)
        {
            for(j=0; j < jeu.hauteur ; j++)
            {
                jeu.plateau[i][j] = "mur.jpg";
            }
        }
    }
    par contre si je fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char* chaine = "texte";
     
    strcpy(*jeu.plateau[0][0],chaine);
    ou meme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strcpy(*jeu.plateau[0][0],"chaine");
    le programme compile mais plante.

    donc pour résumer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    jeu.plateau[0][0]="chaine";    // ca ca marche
    strcpy(jeu.plateau[0][0],"chaine"); // ca ca marche po
    Quelqu'un a une idée?


    edit: je viens de trouvé quelque chose qui fonctionne:
    aussi bizare que ca puisse paraitre :

    jeu.plateau[i][j] = chaine; // ca fonctionne

    je ne savais pas que les assignations sur les strings fonctionnait (a moins qu'il ne s'agit que du pointeur).

    edit2: c'est bien ce qu'il me semblait: l'assignation se fait sur les pointeurs donc ca ne va pas.

    par contre :
    strcpy(chaine2,chaine); // ca ca marche

    donc je bute vraiement la dessus :

    strcpy(jeu.plateau[0][0],chaine); // ca ca marche pas

  2. #2
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Ah les pointeurs !!!!
    Lorsque tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    jeu.plateau[i][j] = "mur.jpg";
    tu assignes à jeu.plateau[i][j] l'adresse mémoire du tableau de caractères "mur.jpg"
    Lorsque tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strcpy(jeu.plateau[0][0],"chaine")
    tu recopies à l'adresse pointée par jeu.plateau[0][0] le tableau de caractères "chaine". Le problème est que tu n'as pas assigné d'adresse à jeu.plateau[0][0] et donc, et c'est une des grandes joies du C, ça marche ou ça marche pas, en effet, si jeu.plateau[0][0] pointe vers une adresse accessible ça fonctionne mais ça risque de bousiller ton code 1000 lignes plus tard si ça pointe vers quelque chose d'inaccessible, tu plantes tout de suite.
    Une méthode simple est de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    jeu.plateau[i][j] = strdup("mur.jpg");
    le strdup s'il existe dans tes lib assure d'obtenir une zone mémoire valide où est recopiée la chaine "mur.jpg", et strdup te renvoie l'adresse mémoire du début de zone. Il ne faut pas oublier de libérer la zone par un free(jeu.plateau[i][j]) à la fin du programme.

    Une autre possibilité consite à faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    jeu.plateau[i][j] = malloc(strlen("mur.jpg") + 1);
    // il faut tester que l'allocation à fonctionné
    if (jeu.plateau[i][j] != NULL)
      strcpy(jeu.plateau[i][j], "mur.jpg");
    Attention à jeu.plateau[i][j] = chaine;
    Tu affectes à jeu.plateau[i][j] une adresse mémoire qui est peut-être localement valide si chaine est une variable locale à une fonction, et donc au sortir de la fonction jeu.plateau[i][j] pointera vers une zone qui sera devenue invalide donc problème potentiel de données corrompues.
    D'autre part, si tu es dans une boucle d'affectation ou j varie par exemple, et que chaine contienne des données qui change (c'est un buffer de lecture par exemple), à la fin de la boucle sur j tous tes jeu.plateau[i][j] pointeront vers la même donnée (la dernière lue), ce qui n'est évidemment pas ce que tu recherches !
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    je ne savais pas que les assignations sur les strings fonctionnait (a moins qu'il ne s'agit que du pointeur).
    Il ne s'agit que du pointeur !

    Tu as une erreur dans ton allocation et les types associés. Comme tu ne donnes pas de précisions, il y a deux possibilités au sujet du champ plateau :

    * La plus classique correspond à ta déclaration de plateau (char***) mais pas à l'allocation. Elle correspond à la structure de données suivante : On alloue un tableau de nbr_carre_largeur pointeurs (char**) (ce que tu fais). Pour chaque pointeur, on alloue un tableau de nbr_carre_hauteur pointeurs (char*) et pour chacun d'entre eux un tableau de TAILLE_MAX char qui contiendra la chaine. Or ton code ne fait pas ces trois étapes d'allocation.

    * L'autre possibilité correspond à ton allocation mais pas au type de plateau : On alloue un tableau (1) de nbr_carre_largeur pointeurs. Pour chaque pointeur, on alloue un tableau (2) de nbr_carre_hauteur éléments, chaque élément faisant TAILLE_MAX char. Le type du tableau (2) est donc char[nbr_carre_hauteur][TAILLE_MAX].
    Les éléments de tableau(2) sont donc du type char[TAILLE_MAX]. Les éléments du tableau (1) doivent être "pointeur vers un tableau char [TAILLE_MAX]" soit char(*)[TAILLE_MAX]. Le type de plateau doit être "pointeur vers un pointeur vers un tableau char [TAILLE_MAX]" : char(**)[TAILLE_MAX].
    On doit donc avoir dans ce cas :
    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
    struct plateau2d
    {
        int taille_carre;
        int largeur;
        int hauteur;
        char (** plateau)[TAILLE_MAX];
    };
     
    jeu.plateau= malloc(nbr_carre_largeur * sizeof *jeu.plateau  );
    for (i=0; i < nbr_carre_largeur ;i++)
        jeu.plateau[i] = malloc(nbr_carre_hauteur * sizeof *jeu.plateau[i]);
     
    strcpy(jeu.plateau[0][0],"chaine00");
    strcpy(jeu.plateau[0][1],"chaine01");
    strcpy(jeu.plateau[1][1],"chaine11");

  4. #4
    Futur Membre du Club
    Inscrit en
    Février 2010
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 4
    Par défaut
    Enfin ca fonctionne:

    merci trap D , le strdup fonctionne
    par contre je ne pense pas que la 2ieme solution fonctionnerai car avec le code ci dessous je refait un malloc de 50 (qui est bien + que le strlen de "mur.jpg")


    diogene : en fait, entre temp, j'ai changer mon allocation mais toujours le meme problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     jeu.plateau= (char***) malloc(sizeof(char**) * nbr_carre_largeur );
        for (i=0; i < nbr_carre_largeur ;i++)
    	{		
    		jeu.plateau[i] = (char**) malloc(sizeof(char*) * nbr_carre_hauteur);
    		for(j=0; j < nbr_carre_hauteur ;j++)
    			jeu.plateau[i][j] = (char*) malloc(sizeof(char) * 50);
    	}

    enfin un grand merci à tous car ça fait 3 jours que je bloque la dessus.

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    diogene : en fait, entre temp, j'ai changer mon allocation mais toujours le meme problème:
    Etonnant, je ne vois pas de problèmes dans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      jeu.plateau= (char***) malloc(sizeof(char**) * nbr_carre_largeur );
      for (i=0; i < nbr_carre_largeur ;i++)
      {
        jeu.plateau[i] = (char**) malloc(sizeof(char*) * nbr_carre_hauteur);
        for(j=0; j < nbr_carre_hauteur ;j++)
           jeu.plateau[i][j] = (char*) malloc(sizeof(char) * 50);
      }
      strcpy(jeu.plateau[0][0],"chaine00");
      strcpy(jeu.plateau[0][1],"chaine01");
      strcpy(jeu.plateau[1][1],"chaine11");

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

Discussions similaires

  1. Réponses: 11
    Dernier message: 05/08/2009, 12h30
  2. Réponses: 2
    Dernier message: 09/03/2006, 15h24
  3. [JDesktopPane] Problème lors de l'insertion d'une JInternalFrame
    Par Invité dans le forum Agents de placement/Fenêtres
    Réponses: 5
    Dernier message: 21/09/2005, 01h38
  4. [POO] Problème lors de l'appel d'une propriété d'un objet.
    Par akecoocoo dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 24/08/2005, 08h51
  5. Problème lors d'un Update sur une date
    Par Nany dans le forum ASP
    Réponses: 3
    Dernier message: 19/05/2004, 22h37

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