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 :

Structure des variables en mémoire


Sujet :

C++

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

    Informations forums :
    Inscription : Mai 2007
    Messages : 2
    Par défaut Structure des variables en mémoire
    Bonjour à tous,
    Question un peu vague, mais la moindre petite information sera plus que bienvenue.
    J'aimerais savoir comment sont structurés les blocs de mémoire aloués dynamiquement.
    Un petit exemple vaut mieux etc...

    Sous windows, éxecutons le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include <string.h>
     
    int main(int *argc, char **argv)
    {
    	char *Test = new char[0xF];
    	strcpy(Test, "aaaabbbbccccdddd");
    }
    Au débuguage on note que Test = 0x00430090.

    On effectue un dump de la mémoire aux alentours de cette adresse :
    (C'est pas beau, mais sans police à chasse fixe, c'est illisible)
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    00430080  0F 00 00 00  .... -> J'ai remarqué que c'était la taille du bloc alloué
    00430084  01 00 00 00  .... -> Keskecé ?
    00430088  29 00 00 00  )... -> What ?
    0043008C  FD FD FD FD  ýýýý -> C'est quoi ?
    00430090  61 61 61 61  aaaa --------------------
    00430094  62 62 62 62  bbbb   Voilà le bloc alloué
    00430098  63 63 63 63  cccc
    0043009C  64 64 64 64  dddd ---------------------
    004300A0  00 FD FD 00  .ýý. -> ?????
    004300A4  00 00 00 00  ....
    De plus, est-ce que cette organisation change en fonction du système d'exploitation, de l'architecture, du language utilisé ou du temps qu'il fait dehors ?

    En vous remerciant par avance, vous avez un très beau forum

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Je n'ai aucune idée de la réponse à ta question, mais pourquoi diable veux-tu savoir ça ?

    Petite suggestion tout de même : je pense que ça dépend de l'environnement ; peut-être même que certains compilos ajoutent des informations pour faciliter le débogage et la détection des corruptions de mémoire.

  3. #3
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Les structures employées par les allocateurs peuvent varier beaucoup. Pas tellement en fonction de l'architecture (qui va généralement imposer peu en plus des contraintes d'alignement). Les langages peuvent jouer un role. Ce qui va jouer un grand role c'est l'algo d'allocation utilisé. Certains compilateurs sont fournis avec deux ou trois allocateurs ayant des caractéristiques différentes.

    Je n'ai aucune idée de ce qui est utile dans celui que tu montres.

  4. #4
    Membre chevronné Avatar de themadmax
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    446
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 446
    Par défaut
    Il doit surement il y avoir des "magic numbers" pour vérifier l'intégriter des buffers. car en Release ( sous Win on obtiens pas les même valeurs )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    0x00000000 : 63 2E 65 78 65 00 00 00 00 00 00 00 03 00 04 00 c.exe...........
    0x00000010 : E2 01 09 00 61 61 61 61 62 62 62 62 63 63 63 63 â...aaaabbbbcccc
    0x00000020 : 64 64 64

  5. #5
    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
    Iop,
    Citation Envoyé par Co_Co
    Bonjour à tous,
    Question un peu vague, mais la moindre petite information sera plus que bienvenue.
    J'aimerais savoir comment sont structurés les blocs de mémoire aloués dynamiquement.
    Un petit exemple vaut mieux etc...

    Sous windows, éxecutons le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include <string.h>
     
    int main(int *argc, char **argv)
    {
    	char *Test = new char[0xF];
    	strcpy(Test, "aaaabbbbccccdddd");
    }
    Je ne vais pas me méler à chercher ce que signifient ces valeurs, mais je vois:

    - Tu réserves une mémoire de 0xF = 15 caractères, dans laquelle tu mets 16 + 1 = 17 caractères.
    Bingo.

    - et le delete ?

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 2
    Par défaut Youpi.
    Tout d'abord, merci pour vos réponses.

    A Laurent Gomila : Dans le but de créer une classe qui simplifie les allocations/désallocations, une bonne connaissance du fonctionnement de la gestion de la mémoire m'est nécessaire.

    A droggo :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include <string.h>
     
    int main(int *argc, char **argv)
    {
    	char *Test = new char[0x10];
    	memcpy(Test, "aaaabbbbccccdddd", 0x10);
    	delete Test;
     
    	return 0;
    }
    Enfin, à Jean Marc Bourguet, merci : en aiguillant mes recherches sur "algorithme allocation mémoire windows" sur google, j'ai pu trouver des choses intéressantes :
    https://www.securinfos.info/jerome/D...loitation.html
    http://ivanlef0u.free.fr/?p=26
    Plus générallement en tapant "structure heap windows", on trouve de la doc en rapport.
    En ce qui concerne Linux ou FreeBSD, je n'ai pas encore cherché, mais ça doit surement être mieux documenté que sous windows.

    Je n'ai pas encore eu le temps d'étudier tout ça, mais déjà :

    En mode debug :
    Le premier mot correspond bien à la taille
    Les mots FD FD FD FD qui encadrent le bloc doivent être des mots magiques (merci themadmax)
    Quand au reste, pour l'instant, indéterminés.

    En mode release :
    Voir les liens plus haut, tout est expliqué.

  7. #7
    Expert confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par défaut
    Pour commencer, je pense que quand on alloue une zone mémoire, il ne faut surtout pas chercher à savoir ce qu'il y a autour. Un appel à malloc(size) renvoit une zone libre et utilisable de la bonne taille qu'on peut libérer avec free() est tout ce qu'il faut savoir.

    Sinon, pour répondre à la question ca dépend de l'implémentation utilisée des librairies standard, c'est à dire: du compilateur (y compris sa version), et de certains paramètres de compilation (debug, release,...), mais aussi du système...

    En général, les fonctions système sont:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    void* system_alloc(size_t length)
    void   system_free(void* ptr, size_t length);
    Il est donc clair qu'un appel à free(ptr) doit pouvoir retrouver la taille du bloc mémoire. La taille est presque toujours présente autour du bloc alloué.

    C'est bien pour cette raison que le code qui désalloue de la mémoire DOIT être celui qui l'alloue. Principalement pour être sur que les mêmes fonctions sont utilisées.
    En C++ c'est encore pire, puisqu'on peut redéfinir le new et le delete par classe.


    Voici une implémentation possible:
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    #ifdef _DEBUG
    #define malloc(size)      malloc_debug(size,__FILE__,__LINE__)
    #define free(ptr)          free_debug(ptr)
    #else
    #define malloc(size)      malloc_release(size)
    #define free(ptr)          free_release(ptr)
    #endif
     
    struct memory_header
    {
         memory_header*  prevAllocated;
         memory_header*  nextAllocated;
         size_t          size;
         const char*  file;
         int               line;
     
    };
     
    static memory_header*  firstAllocated = 0;
    static memory_header*  lastAllocated = 0;
     
    void* malloc_debug(size_t size, const char* file, int line)
    {
         size_t finalsize = size + sizeof(memory_header);
         memory_header* allocated = (memory_header*)system_allocation(finalsize);
         if (allocated->prevAllocated = lastAllocated) 
             lastAllocated->nextAllocated = allocated;
         else
             firstAllocated = allocated;     
         lastAllocated = allocated;
         allocated->nextAllocated = 0;
         allocated->size = size;
         allocated->file = file;
         allocated->line = line;
         return ++allocated;
    }
     
    void free_debug(void* ptr)
    {
        memory_header* hdr = ((memory_header*)ptr) - 1;
        if (hdr->nextAllocated) 
            hdr->nextAllocated->prevAllocated = hdr->prevAllocated;
        else
            lastAllocated = hdr->prevAllocated;
        if (hdr->prevAllocated)
            hdr->prevAllocated->nextAllocated = hdr->nextAllocated;
        else
            firstAllocated = hdr->nextAllocated;
        size_t finalsize = hdr->size + sizeof(memory_header);
        system_free(hdr,finalsize);
    }
    Et voilà... à tout moment je peux savoir qui (quel code) a alloué quoi...

  8. #8
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Voici une implémentation possible:
    Ce n'est pas du tout garanti de marcher, ça peut parfaitement violer les contraintes d'alignement.

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

Discussions similaires

  1. Ordre en mémoire des variables dans une structure
    Par guillaume-13015 dans le forum C
    Réponses: 8
    Dernier message: 12/03/2013, 15h52
  2. gestion des variables en mémoire
    Par tubaas dans le forum MATLAB
    Réponses: 2
    Dernier message: 15/01/2010, 11h13
  3. Des Structures comme variables Globales
    Par mr_samurai dans le forum MATLAB
    Réponses: 3
    Dernier message: 11/01/2008, 19h27
  4. Gestion des variables - mémoire ?
    Par RIVOLLET dans le forum Langage
    Réponses: 4
    Dernier message: 26/10/2002, 12h44
  5. [VB6] [Fichier] Enregistrer des variables de structure
    Par de.bo dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 07/10/2002, 11h09

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