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 :

Rendre une structure non copiable


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2008
    Messages
    187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Octobre 2008
    Messages : 187
    Par défaut Rendre une structure non copiable
    Bonjour,

    est-il possible d'empêcher une structure d'être copiable en C99 ? Mon problème est que j'ai une structure basique de tableau dynamique qui ressemble à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct DynamicArray
    {
        int size;
        int capacity;
        size_t eltsize;
        void* data;
    }
     
    void DynamicArray_Init(struct DynamicArray* array, size_t eltSize);
    void DynamicArray_Add(struct DynamicArray* array, void* value);
    et que si quelqu'un a le malheur d'écrire plus tard:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct DynamicArray arrayA;
    DynamicArray_Init(&arrayA, sizeof(int));
     
    int i = 3;
    struct DynamicArray arrayB = arrayA;
    DynamicArray_Add(&arrayB, &i);
    Alors dans ce cas là, il se peut que la structure A soir invalidée à cause des opérations de realloc potentielles dans le Add.

    J'imagine que la seule solution est de rendre la structure opaque, mais c'est un peu dommage vu que du coup ça n'est plus possible de l'allouer de manière automatique -_-

    Merci d'avance.

  2. #2
    Expert confirmé

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

    Ta structure s'adresse à des programmeurs suffisamment formés, à eux de prendre leurs responsabilités.

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 117
    Billets dans le blog
    148
    Par défaut
    Bonjour,

    Vous pouvez faire en sorte que la structure devienne opaque (que le programmeur ne connaisse jamais son contenu réel). Pour cela, il ne faut jamais lui donné le .h où la structure est déclarée et lui donner assez de fonctions pour "jouer" avec la structure.
    Lorsqu'il a besoin de l'utiliser, il l'utilise seulement à travers des pointeurs et pour sa déclaration, il utilise un bête :
    indiquant que le symbole existe bien, mais que bon, on ne sait pas ce que c'est. Beaucoup de bibliothèque agissent ainsi (SDL 2, libcg, ...)
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Et même la bibliothèque standard, avec les FILE* de fopen, fclose, fread etc

  5. #5
    Membre expérimenté
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2008
    Messages
    187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Octobre 2008
    Messages : 187
    Par défaut
    Citation Envoyé par droggo Voir le message
    Ta structure s'adresse à des programmeurs suffisamment formés, à eux de prendre leurs responsabilités.
    Certes, mais on est jamais à l'abri d'une inattention

    Citation Envoyé par LittleWhite Voir le message
    Vous pouvez faire en sorte que la structure devienne opaque
    Oui c'est ce que je disais, mais je trouve dommage de devoir utiliser ce mécanisme et perdre en même temps la possibilité d'allouer un tableau dynamique sur la pile, mais bon je n'ai pas trop le choix on dirait !

    Sinon je viens d'avoir une idée, qui consisterait à vérifier les erreurs au runtime. Dans le header :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct DynamicArray
    {
        int size;
        int capacity;
        size_t eltsize;
        void* data;
        int signature;
    }
     
    void DynamicArray_Init(struct DynamicArray* array, size_t eltSize);
    void DynamicArray_Add(struct DynamicArray* array, void* value);
    et dans le .c :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void DynamicArray_Init(struct DynamicArray* array, size_t eltSize)
    {
        array->signature = (int) array;
        ...
    }
     
    void DynamicArray_Add(struct DynamicArray* array, void* value)
    {
        assert(array->signature == (int) array);
        ...
    }
    ainsi si un programmeur a le malheur d'assigner un tableau directement, la signature ne sera plus bonne et on aura un assert au runtime.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct DynamicArray arrayA;
    DynamicArray_Init(&arrayA, sizeof(int));
     
    int i = 3;
    struct DynamicArray arrayB = arrayA;
    DynamicArray_Add(&arrayB, &i);    // assert ici car arrayB.signature != &arrayB
    Vous en pensez quoi ?

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dancingmad Voir le message
    Sinon je viens d'avoir une idée, qui consisterait à vérifier les erreurs au runtime. Dans le header :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct DynamicArray
    {
        int size;
        int capacity;
        size_t eltsize;
        void* data;
        int signature;
    }
     
    void DynamicArray_Init(struct DynamicArray* array, size_t eltSize);
    void DynamicArray_Add(struct DynamicArray* array, void* value);
    et dans le .c :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void DynamicArray_Init(struct DynamicArray* array, size_t eltSize)
    {
        array->signature = (int) array;
        ...
    }
     
    void DynamicArray_Add(struct DynamicArray* array, void* value)
    {
        assert(array->signature == (int) array);
        ...
    }
    Vous en pensez quoi ?
    Bonjour

    Pourquoi caster systématiquement en int ? Pourquoi ne pas stocker directement l'adresse elle-même ???

    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
    typedef struct s_DynamicArray
    {
        int size;
        int capacity;
        size_t eltsize;
        void* data;
        struct s_DynamicArray *signature;
    } t_DynamicArray;
     
    void DynamicArray_Init(t_DynamicArray* array, size_t eltSize)
    {
        array->signature = array;
        ...
    }
     
    void DynamicArray_Add(t_DynamicArray* array, void* value)
    {
        assert(array->signature == array);
        ...
    }
    ...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Rendre une ComboBox non éditable
    Par Tangui dans le forum Débuter
    Réponses: 1
    Dernier message: 08/05/2008, 16h22
  2. Rendre une fenêtre non-redimensionnable
    Par TSalm dans le forum Windows
    Réponses: 10
    Dernier message: 15/11/2007, 10h57
  3. Rendre une Page non valide
    Par miniseb dans le forum ASP.NET
    Réponses: 1
    Dernier message: 21/08/2007, 11h14
  4. Réponses: 2
    Dernier message: 16/03/2007, 09h13

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