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 :

"const" cause un segfault


Sujet :

C

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2009
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2009
    Messages : 172
    Points : 191
    Points
    191
    Par défaut "const" cause un segfault
    Salut à tous,

    j'ai une petite question. En ce qui me concerne j'ai toujours pensé que le mot clé "const" servait seulement à rendre une variable "non modifiable". Mais il faut croire que j'ai loupé quelques chose d'important!

    voici un bout de 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
    typedef long printstring_t(void);
    
    typedef struct _ObjVtbl {
            printstring_t * printstring;
    } ObjVtbl;
    
    typedef struct _Obj {
            IExampleVtbl * lpvtbl;
    } Obj;
    
    long printstring(void)
    {
            return(0);
    }
    
    static const ObjVtbl Obj_vtbl = { printstring };
    
    int main(void)
    {
           Obj * obj;
    
           obj = HeapAlloc(GetProcessHeap(), 0, sizeof(IExample));
    
           obj->lpvtbl->printstring = printstring;
    
           obj->lpvtbl->printstring();
    
           return(0);
    }
    Pour ceux qui l'auront compris, j'ai volontairement omis les "this" et consor mais en gros j'essaye de faire un objet C++ en C (J'arrive pas à le lâcher ). Bref...

    Question simple : pourquoi le const me crée un SEGFAULT?

    EDIT : Je précise que le compilo m'avertit bien du schmilblik (c'est plus clair avec gcc).

    cl : warning C4090 : ' =' : different 'const' qualifiers.
    gcc : error : assignment discards qualifiers from pointer target type.

    Merci.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Bonjour,

    Visiblement, ce n'est pas le « const » qui pose problème. Tu confonds beaucoup de choses dans ton code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Obj * obj;
     
    obj = HeapAlloc(GetProcessHeap(), 0, sizeof(IExample));
    Un pointeur n'est pas une référence Java (ni même C++). C'est une vraie variable qui occupe de la place en mémoire et qui n'est faite que pour contenir une adresse mémoire. Lorsque tu écris la ligne ci-dessus. Tu alloues suffisamment de place pour pour un objet « IExample » alors que ton pointeur est censé pointer un objet « Obj ». Ce ne sont pas les mêmes (même si IExample est probablement aussi gros que Obj).

    D'autre part, ces fonctions ne font qu'allouer de la place pour y stocker ces objets. Elles remettent pas automatiquement à zéro cet espace. C'est donc à toi d'initialiser proprement tes objets une fois que tu les a alloués.

    Ensuite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    obj->lpvtbl->printstring = printstring;
    Tu as alloué de la place pour Obj mais :
    • Tu ne l'as pas initialisé. « lpvtbl » pointe donc n'importe où ;
    • Ce champ est un pointeur sur un objet « IExampleVtbl » que tu n'as pas alloué.


    Par conséquent le champ « printstring » est encore inexistant au moment où tu essaie de le renseigner. Rien que ça, ça suffit à faire planter ton programme.

    Puis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static const ObjVtbl Obj_vtbl = { printstring };
    À aucun moment, dans ton programme, tu ne fais référence à l'objet « Obj_vtbl » que tu déclares et définis ici. Ce n'est donc pas le const le responsable.

    Et enfin :

    « return » est un mot-clé, qui de surcroît ne rend pas la main à la fonction qui l'invoque. On ne met donc pas de parenthèses à son argument.

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2009
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2009
    Messages : 172
    Points : 191
    Points
    191
    Par défaut
    Bonjour obsidian,

    Désolé pour le retard de ma réponse, j'ai eut ma réponse 5 minutes après sur les googles groups et en fait j'avais un peu oublié que j'avais posé la question ici avant.

    Mon code est pas super c'est vrai (il est même sûrement horrible j'ose même pas le relire). j'étais un peu pressé et surtout super fatigué donc j'ai voulut simplifier le copié/collé mais au final c'était une mauvaise idée dans l'état où j'étais. Mais merci quand même pour ton aide!

    Concernant mon problème, en fait j'ai trop dévellopé. Voici une version plus courte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    const char * p = "salut";
     
    char * j;
     
    j = p; /* Warning */
    en fait "l'erreur", si je puis dire, vient du fait que lorsque je déclare p constant et lorsque je fait pointer j vers *p rien ne m'empêche de modifier la valeur de *p (supposé constant), en passant par j, donc le compilo me prévient.

    EDIT : Et maintenant que je relis le titre ça me rappelle que justement ça a pas loupé sur le coup, le pointeur p pointait dans mon cas vers une donnée située dans une section read-only de l'executable (data-section), d'où le SEGFAULT.

    cordialement

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

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