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 :

Initialiser char dynamique dans struct


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 5
    Par défaut Initialiser char dynamique dans struct
    Bonjour,

    J'ai codé ça :
    ************************************************
    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
    typedef struct {
       int  x;
       int  y;
       int  valid;
       int  select;
       char *title;
       char *val;
       char *params[];
    } prm;
     
    typedef struct {
       prm prm1;
       prm prm2;
    } prms;
     
     
    int main(void)
    {
    prms test;
     
    test.prm1.x=1;
    test.prm1.area.y=2;
    test.prm1.valid=3;
    test.prm1.select=4;
    test.prm1.title="5";
    test.prm1.val="6";
    test.prm1.params[0]="7";
    test.prm1.params[1]="8";
    ************************************************
    Ca marche, mais je voudrais initialiser tout en une seule fois, comme ici :
    char *test2[]={"5","6"};

    Pourquoi ceci, ci-dessous, ne marche pas ? Que dois-je faire pour y arriver ?
    prms test;
    test.prm1 = {1, 2, 3, 4, "5", "6", {"7", "8"}};

    Ceci non plus :
    prms test;
    test.prm1 = {1, 2, 3, 4, "5", "6", "7", "8"};


    Merci de votre aide.

  2. #2
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char *test2[]={"5","6"};
    prms test;
    test.prm1 = {1, 2, 3, 4, "5", "6", {"7", "8"}};
    1- Il y a une grande différence entre la ligne 1 et la ligne 3 : la ligne 1 est une initialisation (on donne une valeur au moment de la définition); la ligne 3 est une assignation d'une valeur à un objet déjà créé.

    2- Dans la ligne 3, à droite du signe = on a une liste d'initialisation dans un contexte d'assignation. Ce n'est pas possible.

    3- Si on est en C99 , on a la possibilité d'utiliser un objet non nommé (anonyme) et d'envisager :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    test.prm1 = (prm){1, 2, 3, 4, "5", "6", {"7", "8"}};
    4- Mais, ici, on va avoir un problème : prm a la particularité de posséder un membre "flexible array" (le membre params) et on ne pourra pas faire cette assignation, prm se comportant dans ce cas comme si ce membre était absent.

    5-
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Ca marche, mais je voudrais initialiser tout en une seule fois,
    C'est une illusion. Le programme est incorrect :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    prms test;
    ...
    test.prm1.params[0]="7";
    test.prm1.params[1]="8";
    Il n'y a pas de mémoire allouée pour le membre params et le comportement de ces deux lignes est indéfini.
    C'est le premier problème à résoudre ici.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 5
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    typedef struct {
       int  x;
       int  y;
       int  valid;
       int  select;
       char *title;
       char *val;
       char *params[];
    } prm;
     
    typedef struct {
       prm prm1;
       prm prm2;
    } prms;
    Donc il semblerait que mon init se fasse dans "le vide", donc si le tas évolue, mes données vont être écrasées je suppose.

    Alors comment initialiser un élément prm proprement, y compris ajouter des éléments dans le tableau dynamique ?

    Merci

  4. #4
    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
    y compris ajouter des éléments dans le tableau dynamique
    Mais params n'est pas à proprement parler un tableau dynamique. Cette syntaxe permet de déclarer un type sans préciser la dimension du tableau. On peut alors avoir plusieurs objets de ce type ayant des tableaux de dimension différente. Cela ne veut pas dire que le tableau est intrinsèquement extensible : le nombre d'éléments du tableau est déterminé par la mémoire allouée à la structure.
    Une telle structure ne peut être membre d'une structure (cf prms) ou élément d'un tableau.

    Si on veut simplement un membre params redimensionnable, il est plus simple de procéder par malloc(), realloc() du membre params déclaré alors ici en char**

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 5
    Par défaut
    Effectivement j'ai vécu des effets indéfinis dû à mon erreur de conception.
    J'ai finalement opté pour ceci, une grande partie de mes données étant des constantes :

    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
    typedef struct {
       const int  x;
       const int  y;
             int  valid;
             int  select;
       const char title[6];
             char val[20];
       const char params[12][20];
    } prm;
     
    typedef struct {
       prm prm1;
       prm prm2;
    } prms;
     
    ...
     
    prms test = {1,2,0,0,"x","y",{"a","b","c","","","","","","","","",""}},
    	    {1,2,0,0,"w","z",{"d","e","f","g","","","","","","","",""}}
    Je pense que c'est résolu, mais j'aimerais une confirmation, svp et si tu as des remarques pour faire mieux, je suis preneur.

    Merci pour ton aide Diogène.

  6. #6
    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
    On peut éventuellement aussi envisager la forme suivante plus économique :
    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
    typedef struct {
       const int  x;
       const int  y;
             int  valid;
             int  select;
       const char *title;
             char val[20];
       const char *params[12];
    } prm;
      prms test = {
                    {1,2,0,0,"x","y",{"a","b","c",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}},
    	        {1,2,0,0,"w","z",{"d","e","f","g",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}}
                   };
    // ou
      prms test = {
                    {1,2,0,0,"x","y",{"a","b","c"}},
    	        {1,2,0,0,"w","z",{"d","e","f","g"}}
                  };
    Ou encore regrouper les constantes peut donner un code plus localisé et maintenable :
    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
    //-------------------------
    typedef const struct {
       int  x;
       int  y;
       char *title;
       char *params[12];
    }prmconst;
    #define prmconst1 {1,2,"x",{"a","b","c"}}
    #define prmconst2 {1,2,"w",{"d","e","f","g"}}
    //-------------------------
    typedef struct {
       prmconst dsc;
       int  valid;
       int  select;
       char val[20];
    } prm;
     
    typedef struct {
       prm prm1;
       prm prm2;
    } prms;
    prms test = {{prmconst1,0,0,"y"},{prmconst2,0,0,"z"}};

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 5
    Par défaut
    Merci pour les conseils Diogène.

    J'apprécie la forme de définition des constantes via #define, ça évite d'allourdir le code principal en repositionnant les constantes en tête de code.

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

Discussions similaires

  1. Typedef char** ? dans struct
    Par Ojiuiookojbezib dans le forum C
    Réponses: 14
    Dernier message: 30/11/2014, 12h43
  2. Réponses: 7
    Dernier message: 24/11/2011, 10h41
  3. Réponses: 9
    Dernier message: 05/11/2008, 21h26
  4. Réponses: 6
    Dernier message: 24/09/2004, 13h10
  5. [D7] Tableaux dynamiques dans un record
    Par bobby-b dans le forum Langage
    Réponses: 2
    Dernier message: 30/06/2004, 23h23

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