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 :

Espace mémoire contigüe pour une structure


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut Espace mémoire contigüe pour une structure
    Bonjour à tous, voilà le problème qui m'ammène :

    je voudrai savoir s'il est possible de s'assurer que tous les champs d'une structure C soient contenus dans un espace mémoire de manière contigüe ? Il faut bien sur que ma structure puisse contenir un tableau dynamique et des champs de différents type.

    Je vais détailler un peu avec un exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct {
    int a;
    int b[3];
    double *v;
    } maStruct;
    Pour l'exemple disons que lors de l'exécution du programme, j'allouerai pour v une taille de N double. Comment faire (et d'ailleurs est-ce possible ?) pour que ma structure ait une taille de 4 int + N double avec mes différents champs contigüent dans cet espace ? Merci d'avance.

  2. #2
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Salut,

    tous les champs de ta structure sont contenus dans un espace mémoire contigu. Je ne vois donc pas de problème. Par contre, lors de l'allocation dynamique du tableau de double pointé par v, à l'aide de malloc() ou de calloc(), rien ne t'assure que l'espace ainsi alloué soit contigu à l'espace alloué pour ta structure.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Justement, je voudrai savoir si c'est possible (par une bidouille quelconque) de rendre l'espace alloué pour mon tableau dynamique contigüe au reste de ma structure. Je me doute bien que ça doit pas être possible si je déclare ma structure telle quel et que plus loin dans le programme j'alloue mon tableau dynamique, mais si par exemple je déclare un pointeur sur ma structure et que j'utilise une fonction qui me l'alloue (y compris la partie dynamique), est-ce qu'il y a moyen de s'assurer de la contigüité du tableau dynamique avec le reste ?

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par _grom
    je voudrai savoir s'il est possible de s'assurer que tous les champs d'une structure C soient contenus dans un espace mémoire de manière contigüe ?
    Non.

    Il y a des possibilités (packed etc.) selon l'implémentation, mais rien de portable. de plus, il reste le problème de la taille des types qui n'est pas garantie d'une implémentation à l'autre).

    Pour être portable, il faut utiliser des tableaux de unsigned char et mettre les bytes un par un.

    EDIT : J'ai lu le reste de la question. Ce n'est pas un problème de 'contigüe' mais de 'séquentielle'.

    OK. Tu veux utiliser un vieux hack qui consiste à définir une sorte d'entête suivit d'un tableau de taille variable.

    C'est possible comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct mydata
    {
       int size;
       char arr [1];
    };
    (la première fois que j'ai vu ça, j'ai failli engueuler l'auteur !).

    et ça s'utilise, par exemple comme ç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
    29
    30
    31
    32
    33
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    struct mydata
    {
       /* ... */
       int size;
       /* ... */
       char s[1];                   /* dernier champ */
    };
     
    int main (void)
    {
     
       int size = 128;
       struct mydata *p = malloc (sizeof *p + size * sizeof (*p->s));
       if (p != NULL)
       {
          p->size = size;
     
          p->s[0] = 0;
     
          strncat (p->s, "hello world", p->size - 1);
     
          puts (p->s);
          /* liberation */
          free (p), p = NULL;
       }
     
       return 0;
    }
    Pas de Wi-Fi à la maison : CPL

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Merci, je craignais devoir recourir à de telles astuces, me voilà fixé.

    Citation Envoyé par Emmanuel Delahaye
    Pour être portable, il faut utiliser des tableaux de unsigned char et mettre les bytes un par un
    Ok, je dois allouer un tableau de unsigned char de la taille cible de ma structure, mais ensuite pour faire la correspondance entre les champs et les éléments du tableau par contre j'avoue que là je vois pas concrètement comment faire ça...

  6. #6
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Une solution peut-être d'allouer une certaine quantité de mémoire au lancement de ton programme et d'implanter ton propre mécanisme d'allocation de mémoire sur cet espace. Mais je ne comprends pas pourquoi tu désires que l'espace mémoire pointé par v soit contingü à l'espace mémoire alloué pour ta structure.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Points : 361
    Points
    361
    Par défaut
    quel est l'interet d'assurer la contiguité en memoire dans ton cas?

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par reptils
    quel est l'interet d'assurer la contiguité en memoire dans ton cas?
    Cette question est intéressante, parce que les cas où c'est nécessaire sont rares...
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Membre habitué
    Inscrit en
    Octobre 2005
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 32

    Informations forums :
    Inscription : Octobre 2005
    Messages : 141
    Points : 135
    Points
    135
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Cette question est intéressante, parce que les cas où c'est nécessaire sont rares...
    Le developpement sur Playstation, je crois.

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par _grom
    Ok, je dois allouer un tableau de unsigned char de la taille cible de ma structure, mais ensuite pour faire la correspondance entre les champs et les éléments du tableau par contre j'avoue que là je vois pas concrètement comment faire ça...
    Il faut spécifier le format de sortie des données, et écrire le code qui suit la spécification à la lettre. Si la définition du projet est bien faite, il y a une rubrique 'interface' qui définit ce genre de chose.
    Pas de Wi-Fi à la maison : CPL

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Merci pour le vieux hack, ça m'a rafraîchit la mémoire

    Sinon pour répondre à vos questions, je voudrai faire ça pour faciliter la communication de ma structure entre deux sites par MPI (sans recopie supplémentaire dans des buffers d'envoi/réception, directement de struct à struct).

    Alors oui à la réflexion je n'ai pas besoin que le tableau dynamique soit vraiment contigüe au reste, par contre si je veux décrire ma structure C par une structure MPI je dois lui fournir l'emplacement mémoire de chaque champ. Bref, je dois m'assurer que mon tableau dynamique se trouve toujours au même endroit (le même déplacement entre les adresses) par rapport au reste de ma structure lorsque je l'alloue.

  12. #12
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    struct mydata
    {
       /* ... */
       int size;
       /* ... */
       char s[1];                   /* dernier champ */
    };
     
    int main (void)
    {
     
       int size = 128;
       struct mydata *p = malloc (sizeof *p + size * sizeof (*p->s));
       if (p != NULL)
       {
          p->size = size;
     
          p->s[0] = 0;
     
          strncat (p->s, "hello world", p->size - 1);
     
          puts (p->s);
          /* liberation */
          free (p), p = NULL;
       }
     
       return 0;
    }
    Je découvre cette technique. Merci Emmanuel! As-tu un exemple ou écrire ce type de code est nécessaire? Optimization?

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  13. #13
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par mujigka
    Je découvre cette technique. Merci Emmanuel! As-tu un exemple ou écrire ce type de code est nécessaire?
    Non.
    Pas de Wi-Fi à la maison : CPL

  14. #14
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Bien merci à tous, et à Emmanuel en particulier, ton bout de hack me permet de faire ce que je voulais : pour mes communications je passe classiquement l'adresse du début de mon buffer d'envoi (ici ma struct) et lui spécifie la taille de l'envoi, et pareillement pour ma réception directement dans une autre instance de ma struct.

    Alors oui c'est pas très joli de programmer comme ça en général mais dans mon cas c'est une question de performance et d'optimisation (pas de recopies) donc ça me convient parfaitement. Résolu pour moi

  15. #15
    Membre actif
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Points : 284
    Points
    284
    Par défaut
    Les RLE_sprites de la bibliothèque Allegro sont sur ce modèle. D'ailleurs il me semble que leur définition est même avec un :
    char data[0];

  16. #16
    Membre éclairé Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par mujigka
    Je découvre cette technique. Merci Emmanuel! As-tu un exemple ou écrire ce type de code est nécessaire? Optimization?

    Thierry
    J'ai déjà eu affaire à cette technique lorsque je développais du logiciel de base (BSP), notamment pour effectuer des transferts DMA entre deux ressources. Et en effet les blocs à transférer étaient composés d’une entête et d’une zone a taille variable.
    Software Failure. Press left mouse button to continue.
    Guru Meditation #0100000C.000FE800

  17. #17
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Ulmo
    Les RLE_sprites de la bibliothèque Allegro sont sur ce modèle. D'ailleurs il me semble que leur définition est même avec un :
    char data[0];
    C'est une extension de gcc. En C99, on peut mettre
    char data[];
    Pas de Wi-Fi à la maison : CPL

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

Discussions similaires

  1. preallocation de la mémoire pour une structure
    Par kawther dans le forum Interfaces Graphiques
    Réponses: 2
    Dernier message: 03/07/2009, 10h41
  2. confilcting types pour une structure ?
    Par Tymk dans le forum C
    Réponses: 5
    Dernier message: 03/07/2008, 08h59
  3. Réponses: 1
    Dernier message: 28/10/2006, 13h05
  4. Réponses: 6
    Dernier message: 24/03/2006, 18h24
  5. Réponses: 1
    Dernier message: 09/02/2006, 11h03

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