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 :

Structure en C


Sujet :

C

  1. #1
    Membre régulier
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Mars 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : Distribution

    Informations forums :
    Inscription : Mars 2012
    Messages : 8
    Par défaut Structure en C
    Bonjour à toutes et à tous,

    Pour mon programme, j'ai besoin d'une structure contenant une autre structure et deux tableaux de structures.

    J'ai plusieurs questions :

    - le nombre de structures Picture dans Metadata dépend du fichier traîté, comment puis-je faire pour l'allocation de mémoire?

    - on ne connais qu'à l'exécution la taille des champs 'field' et 'value', comment puis-je faire pour l'allocation de mémoire?

    - comment libérer proprement la mémoire allouée?

    Voici mon code :

    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
     
    typedef struct {
    	char	*mime_type;
    	char	*description;
    	int	width;
    	int	height;
    	int	depth;
    	int	colors;
    	int	data_length;
    	char	*data;
    } Picture;
     
    typedef struct {
    	unsigned int	min_blocksize;
    	unsigned int	max_blocksize;
    	unsigned int	min_framesize;
    	unsigned int	max_framesize;
    	unsigned int	sample_rate;
    	unsigned int	channels;
    	unsigned int	bits_per_sample;
    	unsigned long int	total_samples;
    	char	md5sum[16];
    } Info;
     
    typedef struct {
    	char	*field;
    	char	*value;
    } Comment;
     
    typedef struct {
    	Info	info;
    	Comment	*comments;
    	Picture	*pictures
    } Metadata;
    Merci d'avance pour votre aide.

    Edit : message corrigé.

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Et ?

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    typedef struct
    {
        int x;
    }ma_Structure;
     
    typedef struct
    {
        ma_Structure a;
        ma_Structure a[45];
    }mon_tableau;

  4. #4
    Membre régulier
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Mars 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : Distribution

    Informations forums :
    Inscription : Mars 2012
    Messages : 8
    Par défaut
    Pardon, le message a été posté alors que je ne l'ai pas fini.
    Je corrige et je vous renvoi le tout.

  5. #5
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Salut,

    Tu utilises les fonctions malloc (pour allouer) et free pour désallouer comme ceci :

    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
    int field_size;
    int nb_comments;
    // Récupération à l'éxecution de field_size et nb_comments...
    Comment* my_comments = malloc(sizeof(Comment) * nb_comments);
     
    // Imaginons que pour chaque commentaire tu veux allouer la taille nécessaire à field.
    int i;
    for(i=0; i < nb_comments; ++i)
      my_comments[i].field = malloc(sizeof(char) * field_size);
     
    // ... Utilisation
     
     
    // Libération
    for(i=0; i < nb_comments; ++i)
      free(my_comments[i].field);
    free(my_comments);

  6. #6
    Membre régulier
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Mars 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : Distribution

    Informations forums :
    Inscription : Mars 2012
    Messages : 8
    Par défaut
    Merci pour ton aide Trademark.
    J'ai juste un problème lorsque je souhaite faire un printf avec le champs field, j'ai une erreur de segmentation.

    Pourrais-tu m'aider?

    Je te donne le code concerné :

    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
     
                        meta.comments = (Comment*)malloc(block->data.vorbis_comment.num_comments*sizeof(Comment));
     
                        for(i = 0; i < block->data.vorbis_comment.num_comments; ++i) {
     
                            gchar **entries = g_strsplit_set((gchar*)block->data.vorbis_comment.comments[i].entry,"=", -1);
     
                            meta.comments[i].field = malloc(sizeof(char)*sizeof(entries[0]));
                            meta.comments[i].field = UTF8(entries[0]);
                            meta.comments[i].value = malloc(sizeof(char)*sizeof(entries[1]));
                            meta.comments[i].value = UTF8(entries[1]);
     
                            g_strfreev(entries);
                        }
     
                        for(i=0; i < block->data.vorbis_comment.num_comments; ++i)
                            printf("%s\n", meta.comments[i].field);
                            free(meta.comments[i].field);
                            free(meta.comments[i].value);
                        free(meta.comments);
    block->data.vorbis_comment.num_comments est le nombre de structures comment.

    UF8 permet de convertir la chaîne en UTF8.

    J'utilise la GLib pour ce programme.

  7. #7
    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
    4
                            meta.comments[i].field = malloc(sizeof(char)*sizeof(entries[0]));
                            meta.comments[i].field = UTF8(entries[0]);
                            meta.comments[i].value = malloc(sizeof(char)*sizeof(entries[1]));
                            meta.comments[i].value = UTF8(entries[1]);
    La ligne 2 écrase allègrement l'adresse obtenue par le malloc() de la ligne 1. Ceci ne fait pas une copie du tableau renvoyé par UTF8().
    Idem pour les deux lignes suivantes

  8. #8
    Membre régulier
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Mars 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : Distribution

    Informations forums :
    Inscription : Mars 2012
    Messages : 8
    Par défaut
    J'ai changé le code et j'ai fait ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    meta.comments[i].field = malloc(sizeof(char)*strlen(entries[0]));
    strcpy(meta.comments[i].field, UTF8(entries[0]));
     
    meta.comments[i].value = malloc(sizeof(char)*strlen(entries[1]));
    strcpy(meta.comments[i].value, UTF8(entries[1]));
    Est-ce correct?

    Ca ne me donne plus d'erreur.

  9. #9
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Après chaque malloc comme après chaque fonction retournant une valeur il faut tester les codes de retours au cas où une erreur se serait produite.
    Ceci permet d'écrire des messages d'erreurs pour savoir pourquoi le logiciel a planté et ainsi pouvoir retrouvé un peu plus vite les erreurs.

  10. #10
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Que retourne la fonction UTF8 ? Et vu que je présumé que ça retourne un pointeur comment l'alloues-tu ?

    Dans ton cas je vois deux solutions (et c'est deux erreurs) :

    • Soit tu retournes l'adresse d'une variable local à la fonction (ce qui provoquera une segfault à un moment ou à un autre).
    • Soit tu retournes un pointeur que tu as alloué dans ta fonction avec malloc, ce qui n'est pas si mal mais alors c'est en conflit avec ce que tu fais (pas de libération de mémoire, copie inutile, ..).


    Ce qui me semble le plus beau, c'est de passer meta.comments[i].field en argument à UTF8 (ce qui laisse le loisir à UTF8 de retourner un code d'erreur si ça c'est mal passé) comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    // Si "field" est alloué avant.
    UTF8(entries[0], meta.comments[i].field);
    // Si field est alloué dans UTF8 :
    UTF8(entries[0], &meta.comments[i].field);
    // Si tu ne peux pas modifié UTF8 :
    meta.comments[i].field = UTF8(entries[0]); // Ne réserve pas de place pour field avant ! (UTF8 le fait).
    Je te laisse méditer le pourquoi du comment et choisir la solution qui te convient

  11. #11
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Salut,

    Citation Envoyé par Flanders Weasel Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    meta.comments[i].field = malloc(sizeof(char)*strlen(entries[0]));
    strcpy(meta.comments[i].field, UTF8(entries[0]));
     
    meta.comments[i].value = malloc(sizeof(char)*strlen(entries[1]));
    strcpy(meta.comments[i].value, UTF8(entries[1]));
    En plus des dernières remarques je rajouterais que ce genre de code est faux et se retrouve souvent quand on utilise malloc/strcpy. Tu dois donner à malloc la taille de la chaine incluant le 0 terminal, strlen te donne la taille de la chaine en n'incluant pas le 0 terminal.
    Il faut juste penser à faire quelquechose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char* copie = malloc(sizeof(*copie)*(strlen(original)+1));
    strcpy(copie,original);

    Deuxième remarque : tu manipules les charsets. entries est un tableau de chaine encodées avec un certain charset et tu transforme cette chaine en utf8. Tu alloues de la place "de même taille" (cf remarque prec.) que la chaine d'origine dans le charset d'origine pour y placer la version utf8 : ATTENTION la version utf8 peut avoir une longueur différente et parfois supérieure suivant le charset d'origine. Par exemple si le charset d'origine est iso8859-1, la chaine origine="salut éric, ça va ?" contient 19 caractères et est codée sur 20 octets. La même chaine en utf8 contiendra toujours 19 caractères mais sera codée sur 22 octets car les caractères é et ç sont codés sur 2 octets.
    Donc avec ton exemple tu alloues 20 et tu écris 22 => problèmes ...

  12. #12
    Membre régulier
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Mars 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : Distribution

    Informations forums :
    Inscription : Mars 2012
    Messages : 8
    Par défaut
    Bonjour à tous et merci pour votre aide.

    UTF8 est en fait une macro :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define UTF8(string) g_locale_to_utf8(string, -1, NULL, NULL, NULL)
    J'utilise une fonction de la glib pour m'assurer que la chaîne soit encodée correctement : g_local_to_utf8

    La fonction doit s'occuper d'allouer la mémoire nécessaire, je pense.

    Le tableau entries provient de la fonction g_strsplit_set qui me permet de découper une chaîne en plusieurs chaînes.

    Voici le code qui la contient :

    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
     
     
    Metadata *metadata;
     
        for(i = 0; i < nbComments; ++i) {
     
            gchar **entries = g_strsplit_set((gchar*)comments[i].entry,"=", -1);
     
            metadata->comments[i].field = malloc(sizeof(char)*strlen(UTF8(entries[0])));
            strcpy(metadata->comments[i].field, UTF8(entries[0]));
     
            metadata->comments[i].value = malloc(sizeof(char)*strlen(UTF8(entries[1])));
            strcpy(metadata->comments[i].value, UTF8(entries[1]));
     
            g_strfreev(entries);
        }
    J'ai également corrigé le code pour allouer la mémoire pour la chaîne convertie en UTF8 via la macro.

    Je fais les vérifications de malloc, je ne les ai pas mises dans le code pour alléger le post.

  13. #13
    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
    La fonction doit s'occuper d'allouer la mémoire nécessaire, je pense.
    Alors, à quoi servent les malloc() ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    metadata->comments[i].field = malloc(sizeof(char)*strlen(UTF8(entries[0])));

  14. #14
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par Flanders Weasel Voir le message
    Bonjour à tous et merci pour votre aide.

    UTF8 est en fait une macro :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define UTF8(string) g_locale_to_utf8(string, -1, NULL, NULL, NULL)
    J'utilise une fonction de la glib pour m'assurer que la chaîne soit encodée correctement : g_local_to_utf8

    La fonction doit s'occuper d'allouer la mémoire nécessaire, je pense.

    Le tableau entries provient de la fonction g_strsplit_set qui me permet de découper une chaîne en plusieurs chaînes.

    Voici le code qui la contient :

    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
     
     
    Metadata *metadata;
     
        for(i = 0; i < nbComments; ++i) {
     
            gchar **entries = g_strsplit_set((gchar*)comments[i].entry,"=", -1);
     
            metadata->comments[i].field = malloc(sizeof(char)*strlen(UTF8(entries[0])));
            strcpy(metadata->comments[i].field, UTF8(entries[0]));
     
            metadata->comments[i].value = malloc(sizeof(char)*strlen(UTF8(entries[1])));
            strcpy(metadata->comments[i].value, UTF8(entries[1]));
     
            g_strfreev(entries);
        }
    J'ai également corrigé le code pour allouer la mémoire pour la chaîne convertie en UTF8 via la macro.

    Je fais les vérifications de malloc, je ne les ai pas mises dans le code pour alléger le post.
    Salut,

    tu as oublié le +1 pour le 0 terminal dans le malloc.

  15. #15
    Membre régulier
    Homme Profil pro
    Technicien Help Desk
    Inscrit en
    Mars 2012
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Technicien Help Desk
    Secteur : Distribution

    Informations forums :
    Inscription : Mars 2012
    Messages : 8
    Par défaut
    Bonjour,

    Les champs field et value ont une taille qui ne sera définie qu'à l'exécution, c'est pourquoi j'utilise un malloc.

    J'ai réjouté 1 dans le malloc. Tout roule. Merci pour votre aide.

  16. #16
    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
    Si UTF8() fait l'allocation mémoire, à quoi sert le malloc() ? Il fait double emploi et en plus on a une fuite mémoire. Dans ce cas, pourquoi ne pas faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    metadata->comments[i].field = UTF8(entries[0]);

Discussions similaires

  1. recuperation de la structure d'une base
    Par pascalT dans le forum 4D
    Réponses: 7
    Dernier message: 07/06/2006, 15h32
  2. [tables systèmes] extraction de la structure d'une base
    Par laffreuxthomas dans le forum Autres SGBD
    Réponses: 6
    Dernier message: 23/03/2006, 13h24
  3. [VB6] [Fichier] Enregistrer des variables de structure
    Par de.bo dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 07/10/2002, 11h09
  4. Structure de données de type "RECORD"
    Par chaours dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 30/09/2002, 17h10
  5. longueur d'une structure
    Par bohemianvirtual dans le forum C
    Réponses: 6
    Dernier message: 28/05/2002, 18h31

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