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 :

Adresse d'une structure inconnue


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 61
    Par défaut Adresse d'une structure inconnue
    Bonjour a tous, et Bonne Annee ^^

    Je viens vers vous aujourd'hui afin de vous demander un peu d'aide.
    Je me retrouve en effet face a une problématique concernant les structure et les pointeurs en C.

    Pour faire court et être concis, je cherche a déterminer l'adresse d'une structure a partir de l'adresse (pointeur) de l'un de ses membres.
    Le nombre de membres est indéterminé, autant dire que je ne peut pas me baser sur la taille de ses membres.

    De plus, je ne pas comment déterminer le "début" dans le cas ou je pourrais successivement déterminer la taille des éléments "parents" de l’élément dont j'ai l'adresse.

    Voila pourquoi je me retrouve bloque.

    Je manipule assez bien les pointeurs lies aux structures, mais si l'un d'entre vous saurait me donner une piste...

    Merci d'avance

    wILL

  2. #2
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 969
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 969
    Par défaut
    Nai,

    Ben ...

    Si tu ne connais pas l'offset de l'adresse dont tu disposes dans la structure, et que tu n'a pas de moyen pour le récupérer, c'est un peu demander l'altitude absolue du point où je me trouve actuellement, sans autre référence, non ?

  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
    Si tu ne connais pas le type exact de la structure, tu ne peux rien faire.
    Sinon, la connaissance de la taille des différents membres de la structure ne te sera d'aucune aide et il faut te tourner vers offsetof() (<stddef.h>)

  4. #4
    Membre éprouvé
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Par défaut
    Bonjour,

    Ce qu'il faut savoir : "un pointeur sur une structure est un pointeur sr son premier élément". Le mot élément sous-entend également les champs de bits :

    Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.
    Sinon je rejoins l'avis des autres, à savoir, que si la fonction ne voit pas la définition de la structure elle ne peux rien faire de façon sûre et portable. Pour finir, la taille d'une structure n'est pas forcément la somme des tailles de ses membres (c'est même rare que ce soit le cas).

    Peut être en nous fournissant plus de détails sur le contexte on arriverait à te proposer une alternative.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 61
    Par défaut
    Suite a la lecture de vos réponses je ne sais pas quoi vous dire.
    Voila l’énonce de ce que je tente de faire.

    Creer la fonction get_struct_ptr qui a le prototype suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     t_whatever   *get_struct_ptr(int *member_ptr);

    t_whatever etant definie de la maniere suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      typedef struct       s_whatever
       {
         ...
         int        member;
         ...
       }            t_whatever;

    Les '...' veulent dire que l'on peut mettre n'importe quels champs dans
    la structure 's_whatever' avant et apres le champ 'member'.
    Un exemple de structure 's_whatever' est donne dans
    le fichier 'ptr_tricks.h'.

    La fonction 'get_struct_ptr' prend donc en parametre un pointeur sur
    le champ 'member' d'une structure 's_whatever' et doit
    tout simplement renvoyer un pointeur sur cette structure.

  6. #6
    Membre éprouvé
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Par défaut
    Au risque de créer un débat, je doute de l'utilité d'un tel exercice; en C, je ne vois pas où est-ce que cela peut-il être significatif. Car si je peux envoyer l'adresse d'un membre de structure, alors je peux envoyer l'adresse de la structure même .

    Sinon la solution que je vois, est que tu définisse une variable de type t_whatever, que tu regarde le décalage entre ce même membre passé en argument et l'adresse initiale de cette variable; pour ensuite appliquer ce décalage au pointeur que tu as reçu en paramètre.

    Tu pourrais utiliser un char* pour éviter des problèmes d'arithmétiques des pointeurs.

    (Je te mettrai un exemple plus tard; mais tu peux déjà y réfléchir).

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 61
    Par défaut
    Plop.

    Le sujet n’étant pas très explicite, je ne sais pas si cela est faisable.
    Sinon je pense avoir compris l’idée. Je vais essayer cela cet aprem, et je ferais un retour dans la soirée

    Merci a toi

    wILL

  8. #8
    Membre éprouvé
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Par défaut
    Voici une version :

    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
    #include <stdio.h>
    #include <stddef.h>
     
    typedef struct
    {
        char t[5];
        unsigned long int ul;
     
        int indicateur;
     
        float f;
        double lf;
     
    } t_whatever;
     
    t_whatever * get_struct_ptr(int * indic);
     
    int main(void)
    {
    	t_whatever s;
     
    	printf("&s = %p\tget_struct_ptr() = %p\n",(void*)&s,(void*)get_struct_ptr(&(s.indicateur)));
     
    	return 0;
    }
     
    t_whatever * get_struct_ptr(int * indic)
    {
        t_whatever s;
        ptrdiff_t decalage = (void*)&(s.indicateur) - (void*)&s;
     
        char * tamp = (char*) indic;
     
        if(!tamp)
            return NULL;
     
        return (t_whatever*)(tamp - decalage);
    }
    (Il peut y avoir des choses à dire sur la portabilité ).

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 61
    Par défaut
    Merci pour ta précieuse aide.
    J'avais fait quelque chose dans le style, mais ton code est plus clair, et je pense que l'utilisation du type ptrdiff_t est approprie dans le cas de cet exercice.

    Merci beaucoup

    wILL

  10. #10
    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
    ptrdiff_t decalage = (void*)&(s.indicateur) - (void*)&s;
    Ce genre d'opérations entre void * n'est pas standard (puisqu'elle nécessite de connaitre le type de l'objet pointé)

    Peut être remplacé par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ptrdiff_t decalage = offsetof(t_whatever,indicateur) ;
    ce qui supprime en même temps la raison d'être de l'objet s.

  11. #11
    Membre éprouvé
    Inscrit en
    Juin 2008
    Messages
    91
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 91
    Par défaut
    Bien vu. Dans ce cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    size_t decalage = offsetof(t_whatever,indicateur) ;
    Ou sinon faire une conversion en char* au lieu de void* :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ptrdiff_t decalage = (char*)&(s.indicateur) - (char*)&s;
    Les types char* et void* sont tellement liés historiquement que je les ai confondus (en ce qui est de l'arithmétique). Ce qui est étonnant dans cette affaire c'est qu'ils subissent les mêmes règles d'alignement pourtant.

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 61
    Par défaut
    Je ne maitrise pas ces subtilités, mais je vous remercie tout les deux pour votre aide

  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
    Ce qui est étonnant dans cette affaire c'est qu'ils subissent les mêmes règles d'alignement pourtant.
    C'dst prévu par la norme :

    n1256 :
    6.2.5 Types
    ....
    27 A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.

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

Discussions similaires

  1. [DOM] Analyser du XML ayant une structure inconnue
    Par bdaboah dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 28/01/2008, 14h17
  2. Adresse/offset du champs d'une structure
    Par ludo894 dans le forum C
    Réponses: 29
    Dernier message: 24/01/2007, 10h58
  3. Retourner l'adresse d'une structure
    Par insomniak dans le forum C++
    Réponses: 12
    Dernier message: 11/05/2006, 18h42
  4. passer l'adresse d'un membre d'une structure ?
    Par tintin72 dans le forum C
    Réponses: 6
    Dernier message: 27/12/2005, 12h20
  5. Ecrire l'adresse d'une structure dans un uint32
    Par Steph12 dans le forum C++
    Réponses: 6
    Dernier message: 17/03/2005, 16h31

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