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 :

operator new sans delete


Sujet :

C++

  1. #1
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut operator new sans delete
    Bonjour à tous,
    Je suis actuellement dans la lecture d'un excellent bouquin sur la programmation de jeu, une partie traite des classes optionnelles voila un bout du 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
    // Base :
    template <unsigned long size>
    class optional_base
    {
    public:
    	optional_base();
    	optional_base(const optional_base &t);
     
    	optional_base & operator = (const optional_base &t);
     
    	bool const Valid() const;
    	bool const UnValid() const;
     
    protected:
    	bool m_bValid;
    	char m_data[size];
    };
     
    // Optional :
    template <class T>
    class optional : public optional_base<sizeof(T)>
    {
    public:
     
    	// Constructeurs...
    	// Operateurs...
    private:
     
    	const T * const GetT() const	{ return reinterpret_cast<const T * const>(m_data); }
    	T * const GetT()		{ return reinterpret_cast<T * const>(m_data); }
    	void Construct(const T &t)	{ new (GetT()) T(t); }
    	void Destroy()			{ GetT()->~T(); }
    };
    Seulement c'est la première fois que je vois l'opérateur new utilisé de cette manière, il n'y a de delete associé nulle part dans le code et GetT dans ce cas retourne un T*const donc les données ne sont pas sencé être modifié sauf si j'ai rien compris....... Si vous pouviez m'éclairer sur ce mystère , si il faut plus de détail sur le code n'hésitez pas à demander
    Merci d'avance

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    C'est un placement new, cf. cette entrée de la FAQ.
    Un new "normal" est séparé en deux : allocation de la mémoire et initialisation, un placement new (comme son nom l'indique un peu) se contente d'effectuer la partie initialisation (donc d'appeler le constructeur en gros).

    edit : il y a une ) en trop dans le corps de Construct a priori.

    MAT.

  3. #3
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Si la méthode retourne un T * const, alors c'est le pointeur qui est constant, pas la donnée pointée .

    C'est d'ailleurs parceque la donnée retournée peut être modifiée que la fonction elle même n'est pas const.

  4. #4
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    il y a une ) en trop dans le corps de Construct a priori
    Petite faute d'inattention c'est réglé... Merci beaucoup pour le lien sur la faq je l'avais loopé . En tout cas tout est limpide désormais concernant la syntaxe
    Si la méthode retourne un T * const, alors c'est le pointeur qui est constant, pas la donnée pointée
    A vrai dire je ne me suis jamais vraiment posé la question pour moi "const T *" était associé à un pointeur constant et du coup "const T * const" à un pointeur constant sur donnée constante(d'après ma logique ) Mais alors ce que je comprend pas c'est pourquoi utiliser ces deux syntaxes pour définir la même chose mais surtout pourquoi mettre deux 'const' sachant que l'un d'entre eux ne veut strictement rien dire....
    En tout cas merci beaucoup pour votre aide

    Edit : Finalement le compilateur ne semble pas apprécier sans les parenthèse donc en fait il en manquait une je suppose, pour compiler :

  5. #5
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 965
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 965
    Par défaut
    Wue,
    Citation Envoyé par babar63 Voir le message
    alors ce que je comprend pas c'est pourquoi utiliser ces deux syntaxes pour définir la même chose mais surtout pourquoi mettre deux 'const' sachant que l'un d'entre eux ne veut strictement rien dire....
    Attention : un pointeur constant signifie qu'on ne peut pas le modifier, n'est pas la même chose que "données pointées constantes".

    Par exemple, avoir un pointeur constant n'interdit absolument pas de modifier les données pointées, SAUF si elles-mêmes sont déclarées constantes.

  6. #6
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Pour être tout à fait précis sur la constance avec les pointeurs :

    La donnée et le pointeur sont constants :
    const T * const ou T const * const

    ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int i, j;
    int const * const p_i = &i;
     
    //on ne peut pas modifier i à partir de  p_i
    //*p_i = 10 interdit
     
    //on ne peut pas modifier p_i
    //p_i = &j interdit

    La donnée est constante mais pas le pointeur :
    const T * ou T const *
    ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int i, j;
    int const * p_i = &i;
     
    //on ne peut pas modifier i à partir de  p_i
    //*p_i = 10 interdit
     
    //on peut modifier p_i
    p_i = &j; //ok

    Le pointeur est constant mais pas la donnée :
    T * const
    ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int i, j;
    int * const p_i = &i;
     
    //on peut modifier i à partir de  p_i
    *p_i = 10; //ok
     
    //on ne peut pas modifier p_i
    //p_i = &j interdit

    Pour faciliter la mémorisation de ce qui est constant, le mieux est de tojours utiliser la syntaxe const après (T const * const), puisque pour les pointeurs constants c'est obligé.
    Dans ce cas ce qui est constant se situe avant le const.
    Et puis cette règle n'induit pas vraiment en erreur dans le cas ou on utilise le const avant (const T * const) puisqu'on voit vite qu'il n'y a rien avant.


    La en parle

  7. #7
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Et pour ce qui est des fonctions membres const :
    une fonction membres const ne doit pas modifier ou permettre de modifier l'instance à laquelle elle appartient (il y a un cas particulier avec le mot clef mutable).
    Et donc en conséquence, seul les fonctions membres const pourront être appellées sur les objets constant.

    ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    optional<int> const opt;
    opt.GetT(); //l'objet opt est constant, c'est donc la fonction déclarée const qui sera utilisée, et le pointeur retournée sera int const * const;
    //Si seule la fonction non const avait été déclarée, la compilation ne serait pas passée.

    Il y a donc une réelle différence entre les deux fonctions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    const T * const GetT() const;
    T * const GetT();
    Les 2 renvois un pointeurs constant vers une donnée membre de l'instance (m_data).
    Mais la première renvois un pointeur constant sur donnée constante, il ne permet donc pas de modifier m_data.
    La deuxième version le permet.

    C'est pourquoi la première fonction peut être déclarée const.


    La en parle

  8. #8
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Vu de ce coté tout est logique en fait je confondais "const T *" et "T * const". C'est la raison pour laquelle je ne saisissais pas le code puisque pour moi la donnée ne pouvait pas être modifié . C'est vrai que dans ce cas il est préférable d'utiliser const après pour mieux de compréhension... Encore merci pour vos réponses claires et précises qui m'ont permis d'y voir plus clair sur ce point

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par MatRem Voir le message
    Si la méthode retourne un T * const, alors c'est le pointeur qui est constant, pas la donnée pointée .
    On ne peut pas renvoyer un scalaire constant en C++. Dans :
    le const est tout simplement ignoré, comme dans :

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par babar63 Voir le message
    Je suis actuellement dans la lecture d'un excellent bouquin
    Bof...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    template <unsigned long size>
    class optional_base
    {
    	char m_data[size];
    };
     
    template <class T>
    class optional : public optional_base<sizeof(T)>
    {
    	void Construct(const T &t)	{ new (GetT()) T(t); }
    };
    Qu'est-ce qui va garantir l'alignement de m_base? Comment ce code peut avoir la moindre chance de marcher?

  11. #11
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Il s'agit de Game Coding Complete (Second Edition). Et oui je confirme le livre est excellent , même si il est possible de trouver quelques erreur de code sur presque 900 pages je pense que ce code a du marcher d'une manière ou d'une autre, il est présenté comme un des outils dont utilisé l'auteur (enfin la je m'avance un peu )... Pour en revenir à l'alignement peut être quelque chose ma échappé mais n'est-il pas possible de le désactiver simplement?

    EDIT : En fait c'est stupide le sizeof en revanche garantit bien l'alignement...

  12. #12
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par babar63 Voir le message
    Il s'agit de Game Coding Complete (Second Edition). Et oui je confirme le livre est excellent , même si il est possible de trouver quelques erreur de code sur presque 900 pages je pense que ce code a du marcher d'une manière ou d'une autre
    Sur certains processeur les accès non alignés sont "seulement" beaucoup plus lents. (Pour des jeux c'est fâcheu.)

    Citation Envoyé par babar63 Voir le message
    (enfin la je m'avance un peu )... Pour en revenir à l'alignement peut être quelque chose ma échappé mais n'est-il pas possible de le désactiver simplement?
    C'est une caractéristique du processeur.

    Citation Envoyé par babar63 Voir le message
    EDIT : En fait c'est stupide le sizeof en revanche garantit bien l'alignement...
    Pardon?

  13. #13
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Voila ce que je pense : Les données de l'objet T est représenté par un tableau de char, par défaut cette structure est alignée, et la taille du tableau devrait être correct puisqu'on utilise sizeof(T). Quand je disais qu'il garantissait bien l'alignement je voulais dire que le reinterpret_cast fonctionnerait (du moins je pense...). Pour ce qui est du placement new c'était le sujet du topic donc forcément je ne vais pas trop m'avancer mais j'ai cru comprendre que c'était simplement l'appel au constructeur de l'objet (l'allocation étant déjà effectué), le pointeur sur la zone étant valide et la taille correct je ne vois pas d'où vient le problème... Peut-tu me dire sur quel point je me trompe?

    EDIT : En relisant plus correctement la faq c'est vrai qu'il est bien préciser que l'objet doit être correctement aligné pour utiliser le placement new, donc si c'est le cas aucun problème pour le code je suppose? Par défaut le compilateur aligne bien non? il y aurait donc danger seulement si on "trafique" l'alignement? ...Dites moi si j'ai tout faux

    EDIT2 : En tout cas je crois que je vais devoir réviser mes cours, réguler mon optimisme sur le livre et faire des tests histoire de mieux comprendre

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par babar63 Voir le message
    Voila ce que je pense : Les données de l'objet T est représenté par un tableau de char, par défaut cette structure est alignée,
    Pourquoi le serait-elle?

    Citation Envoyé par babar63 Voir le message
    et la taille du tableau devrait être correct puisqu'on utilise sizeof(T).
    Ce n'est pas le problème. C'est l'alignement qui est en cause.

    Citation Envoyé par babar63 Voir le message
    Quand je disais qu'il garantissait bien l'alignement je voulais dire que le reinterpret_cast fonctionnerait (du moins je pense...).
    Au delà du reinterpret_cast (qui sur les archi courantes "fonctionne" toujours), il faut pouvoir construire et manipuler un objet à cette adresse, sans générer un segfault ou équivalent.

    Citation Envoyé par babar63 Voir le message
    Pour ce qui est du placement new c'était le sujet du topic donc forcément je ne vais pas trop m'avancer mais j'ai cru comprendre que c'était simplement l'appel au constructeur de l'objet (l'allocation étant déjà effectué),
    C'est exactement ça.

    Citation Envoyé par babar63 Voir le message
    le pointeur sur la zone étant valide et la taille correct je ne vois pas d'où vient le problème...
    Le problème vient de ce que le pointeur n'est pas valide, car non-aligné.

    Citation Envoyé par babar63 Voir le message
    Peut-tu me dire sur quel point je me trompe?
    Sur le fait que l'alignement est un "non-problème". (Méfiez-vous des "non-problèmes".)

    Citation Envoyé par babar63 Voir le message
    Par défaut le compilateur aligne bien non? il y aurait donc danger seulement si on "trafique" l'alignement? ...Dites moi si j'ai tout faux
    Selon la norme, tu as tout faux.

    Après, je ne sais pas ce que fait "par défaut" ton compilateur.

  15. #15
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par corrector Voir le message
    le const est tout simplement ignoré, comme dans :
    Ce n'est pas tout à fait vrai. Vue de l'extérieur, cette fonction est effectivement identique à si on avait déclaré Mais vue de l'intérieur, i est une variable constante, ce qui ne serait pas le cas sinon (ce serait juste une variable dont les modifications ne seraient pas visible du code appelant).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  16. #16
    Inactif  
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    1 958
    Détails du profil
    Informations personnelles :
    Âge : 60
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 1 958
    Par défaut
    Citation Envoyé par corrector Voir le message
    le const est tout simplement ignoré, comme dans :
    Comme le dit JolyLoic, c'est faux ce que tu dis. Si tu essaies de compiler ceci
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int identite (const int i)
    {
       i = 1 ;
       return i ;
    }
    Tu obtiens une erreur à la compilation. En fait, il serait intelligent d'en mettre régulièrement. Cela rajoute une sécurité supplémentaire.

  17. #17
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Garulfo Voir le message
    Comme le dit JolyLoic, c'est faux ce que tu dis. Si tu essaies de compiler ceci
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int identite (const int i)
    {
       i = 1 ;
       return i ;
    }
    Tu obtiens une erreur à la compilation.
    Il ne faut pas plus lire dans ce que j'ai écris que ce que j'ai écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int identite (const int i);
    est synonyme de
    Dans une définition de fonction, ça n'est pas équivalent évidemment.

    Citation Envoyé par Garulfo Voir le message
    En fait, il serait intelligent d'en mettre régulièrement. Cela rajoute une sécurité supplémentaire.
    Je ne suis pas sûr : est-ce que ce genre d'erreurs se arrive vraiment?

  18. #18
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Alors je suppose que le code provenant du livre se basé uniquement sur des structures de base alignés c'est vrai qu'il y à une partie juste avant sur l'utilisation de la mémoire et l'importance de l'alignement dans les jeux çaE ne doit pas être un hasard... En revanche très dommage de donner le code sans plus d'avertissement

    Y à t-il une explication au fait que la structure doit être alignée pour appelé le new placement? Si vous connaissez des bonnes documentations sur internet traitant de çà je suis preneur

    Merci beaucoup pour ton aide corrector

    EDIT : Après quelques tests sur visual 2005 (32bits) voilà le résultat :
    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
    struct MyStruct1
    {
    	char c;
    	int i;
    	char c2;
    };
     
    #pragma pack( push, 1 )
     
    struct MyStruct2
    {
    	char c;
    	int i;
    	char c2;
    	char unused[2];
    };
     
    #pragma pack( pop )
     
    int main(int argc, char *argv[])
    {
    	cout << "size of MyStruct1 :" << sizeof(MyStruct1)*8 << endl;
    	cout << "size of MyStruct2 :" << sizeof(MyStruct2)*8 << endl;
     
    	system( "pause" );
    	return 0;
    }
    Resultat :
    size of MyStruct1 :96
    size of MyStruct2 :64
    Conclusion : le compilateur aligne mais pas de manière optimal

  19. #19
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par babar63 Voir le message
    Alors je suppose que le code provenant du livre se basé uniquement sur des structures de base alignés
    Je ne comprends pas ce que veux dire.

    Citation Envoyé par babar63 Voir le message
    ... En revanche très dommage de donner le code sans plus d'avertissement
    Je ne dirais pas le contraire.

    Citation Envoyé par babar63 Voir le message
    Y à t-il une explication au fait que la structure doit être alignée pour appelé le new placement?
    Tout simplement parce qu'un accès à une donnée, mettons à une adresse A, ne peut être fait que si cette donnée peut effectivement être stoquée à l'adresse A.

    Citation Envoyé par babar63 Voir le message
    Merci beaucoup pour ton aide corrector
    Je t'en prie.

    Citation Envoyé par babar63 Voir le message
    EDIT : Après quelques tests sur visual 2005 (32bits) voilà le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct MyStruct1
    {
    	char c;
    	int i;
    	char c2;
    };
    Le calcul est simple (m(n) étant le n-ième membre, partant de 0, N le nombre de membres) :
    offset(m(0)) = 0
    offset(m(n+1)) = min { x tq x >= offnext(m(n)) et x mod alignof(m(n+1)) = 0 }
    offnext(m(n)) = offset(m(n)) + sizeof(m(n))

    Comme vous pouvez le voir, offnext(m(n)) est l'offset de la première place disponible dans la structure après le membre m(n).

    Soit structure(m) la structure dont les membres sont les m(n) :

    alignof(structure(m)) = PPCM(alignof(m(n))) (pour 0<=n<N)
    sizeof(structure(m)) = min { x tq x >= offnext(m(N)) et x mod alignof(structure(m)) = 0 }

    Puisque les alignements sont des puissances de 2, on a:
    PPCM(alignof(m(i))) = max(alignof(m(i)))
    et donc
    alignof(structure(m)) = max(alignof(m(i)))

    La définition de sizeof(structure(m)) équivaut à ajouter à la structure un membre qui serait la structure elle-même, après son dernier membre, et à calculer l'offset de ce membre inventé, formellement :

    soit m' tq
    m'(n) = m(n) (pour 0<=n<N)
    m'(N) = structure(m)
    et
    s'(m) = structure(m')

    on voit que sizeof(structure(m)) = offset(m'(N))

    (J'espère ne pas m'être emmêlé dans mes notations.)

    Ce qui nous donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    membre type  taille alignement offset offnext
    c      char  1      1          0      1
    i      int   4      4          4      8
    c2     char  1      1          8      9
     
    invent MyStruct1    4          12
    (invent est le membre inventé)
    (Désolé, je ne sais pas comment faire un vrai tableau.)

    Finalement :
    alignof(MyStruct1) = 4
    sizeof(MyStruct1) = 12

    Citation Envoyé par babar63 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #pragma pack( push, 1 )
     
    struct MyStruct2
    {
    	char c;
    	int i;
    	char c2;
    	char unused[2];
    };
     
    #pragma pack( pop )
    Je suppose qu'on défini un alignement de 1. C'est à dire que le compilateur n'aligne plus rien, ça ne veut pas dire que le processeur va changer d'avis sur l'alignement.

    Citation Envoyé par babar63 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main(int argc, char *argv[])
    {
    	cout << "size of MyStruct1 :" << sizeof(MyStruct1)*8 << endl;
    	cout << "size of MyStruct2 :" << sizeof(MyStruct2)*8 << endl;
     
    	system( "pause" );
    	return 0;
    }
    Resultat : Conclusion : le compilateur aligne mais pas de manière optimal
    Pourquoi pas optimale? Tu peux préciser ce qui ne va pas?

    Et pourquoi donner les résultats en bits en pas en octets?

  20. #20
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Les deux structures crees devaient stocker deux char et un int, dans le premier cas, en laissant le compilateur aligner, la taille de la structure est de 96bits. Dans le second cas en alignant moi-meme(char unused) j'obtiens 64bits, c'est pour ca que j'ai dit que le compilateur n'alignait pas de maniere optimale... si je remplace la premiere structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct MyStruct1
    {
            char c;
            char c2;
            int i;
    };
    La taille passe a 64bits...

    Pourquoi en bit... je travaille sur une platforme 32bits et a moins d'avoir rien compris une structure alignee signifie que la taille est multiple de 32bits...voila pourquoi, je me trompe?

    NOTE : C'est vrai que les notations donne mal au crane mais le tableau aide bien encore merci de te donner autant de mal

    NOTE : Desole pour les accents je suis sur qwerty

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Redéfinition opérateurs new et delete globaux
    Par bolhrak dans le forum C++
    Réponses: 8
    Dernier message: 30/07/2007, 11h34
  2. surdefinition operateur new et delete
    Par johjoh dans le forum C++
    Réponses: 23
    Dernier message: 08/12/2006, 10h10
  3. intrigue sur la surcharge du new et delete
    Par swirtel dans le forum C++
    Réponses: 12
    Dernier message: 07/09/2006, 15h23
  4. Segmentation fault sur new[] et delete[]
    Par Don ViP dans le forum C++
    Réponses: 4
    Dernier message: 30/04/2006, 00h29
  5. Namespace et surcharge operator new/delete
    Par ZeLegolas dans le forum C++
    Réponses: 11
    Dernier message: 26/07/2005, 13h55

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