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 :

Gestion memoire par region et mmap


Sujet :

C

  1. #1
    Futur Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 14
    Points : 7
    Points
    7
    Par défaut Gestion memoire par region et mmap
    Bonjour a tous! Je suis nouveau sur le forum mais egalement nouveau en C. Dans un de mes cours, je dois coder une petite librairie de gestion de memoire par region dans ce meme langage. Oui mais voila, je recontre quelques petits problemes (de conceptualisation surtout) qui m'empechent d'avancer.

    En fait, on nous oblige a utiliser la fonction : mmap (NULL, nbytes, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)
    pour notre allocation de memoire "bas-niveau". J'ai lu la doc sur mmap et c'est pas la que le probleme ce pose.

    On nous demande dans l'enonce que :
    "mmap ne peut allouer que des multiples de pages (i.e. des multiples de 4KB par exemple). Pour des regions de grande taille ou de taille illimitee, on peut sans autres dedier chaque page a une region. Mais pour des regions de petite taille (e.g. qui ne contiennent que un ou deux objects de quelques bytes), cela peut entraıner un gaspillage inacceptable, donc il faudra s’arranger pour partager des pages entre plusieurs de ces petites regions."

    Et c'est la que mon probleme se pose. Il est possible d'allouer uniquement des pages entieres de memoire donc, lorsque nous creons notre premiere region, aussi petite soit-elle, nous allouons une premiere page. Maintenant, lorsque l'on decide d'allouer une autre region de taille inferieur a la taille de la page moins la taille de la region precedent, comment recuperer la page deja allouee pour y inserer la nouvelle region?

    A vous tous merci!

    PS : voici l'enonce du probleme : http://www.iro.umontreal.ca/~monnier/2035/tp2/tp2.pdf

    et voici le code qu'on nous fournit a la base :
    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    /* rgn.c --- Routines d'allocation mémoire par régions.  */
     
    #include "rgn.h"
    #include <sys/mman.h>
    #include <unistd.h>
     
    /* L'allocation de bas niveau se fait avec "mmap":
     
       ptr = mmap (NULL, nbytes,
                   PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)
     
       où nbytes doit être un multiple de la taille d'une page, i.e. un multiple
       de sysconf(_SC_PAGESIZE).  Cette mémoire peut être libérée plus tard
       avec "munmap".
       Voir "man mmap", "man munmap", et "man sysconf" pour de plus amples
       informations.  */
     
     
    /* Type d'un descripteur de région.  */
    struct rgn {
       /* ... */
    };
     
    /* Crée une nouvelle région dont la taille maximale est "maxbytes", ou
       qui peut grandir sans limite si "maxbytes" est égal Ã* 0.  */
    rgn  *rgn_new (size_t maxbytes)
    {
       /* ... */
    }
     
     
    /* Alloue un espace de "nbytes" dans la région "r" et renvoie son adresse,
       ou NULL si l'allocation échoue.  */
    void *rgn_alloc (rgn *r, size_t nbytes)
    {
       /* ... */
    }
     
     
    /* Libère l'espace occupé par la région "r".  */
    void  rgn_free (rgn *r)
    {
       /* ... */
    }
     
    #if 0
    /* On put implanter "malloc" au-dessus de nos régions.  */
     
    void *malloc (size_t nbytes)
    {
       rgn *r = rgn_new (nbytes + sizeof (rgn*));
       rgn **x = rgn_alloc (r, nbytes + sizeof (rgn*));
       *x = r;
       return x+1;
    }
     
    void free (void *ptr)
    {
       rgn **x = ptr;
       rgn_free (x[-1]);
    }
     
    #endif
     
    /* arch-tag: 64fdb756-d391-4f17-98b7-a5ecff6b652f */
    et pour finir, le code rgn.h :
    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
    /* rgn.h --- Routines d'allocation mémoire par régions.  */
     
    #ifndef RGN_H
    #define RGN_H
     
    #include <stdlib.h>
     
     
    /* Type d'un descripteur de région.  Reste opaque ici: son implantation
       n'est visible que dans rgn.c.  */
    typedef struct rgn rgn;
     
    /* Crée une nouvelle région dont la taille maximale est "maxbytes", ou
       qui peut grandir sans limite si "maxbytes" est égal Ã* 0.  */
    rgn  *rgn_new (size_t maxbytes);
     
    /* Alloue un espace de "nbytes" dans la région "r" et renvoie son adresse,
       ou NULL si l'allocation échoue.  */
    void *rgn_alloc (rgn *r, size_t nbytes);
     
    /* Libère l'espace occupé par la région "r".  */
    void  rgn_free (rgn *r);
     
    #endif
     
    /* arch-tag: ac7599d3-b67d-4810-84fd-f18d104cb859 */
    Encore une fois merci!

  2. #2
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    On peut répondre de plusieurs manières à ton problème, qui n'est pas ce qu'il y a de plus simple lorsque l'on débute, surtout avec mmap (j'aurais plutôt choisi sbrk, mieux adapté). Je te propose dans la suite du message une solution, qui est peut-être la plus simple, à moins que tes profs n'aient pensé à autre chose.

    Une solution consiste à voir et considérer toute la mémoire à laquelle tu accès (c'est-à-dire celle libre) comme une liste chaînée. Le principe n'est pas si compliqué.

    Tu dois conserver dans une variable globale l'adresse de la tête de ladite liste. Pour commencer, tu l'initialises à NULL.

    La mémoire NE DOIT PAS, pour des questions évidentes de portabilité, être vue comme une suite de char : en effet, il vaut mieux la considérer comme un grand ensemble d'éléments de type struct cartouche_t, par exemple, où struct cartouche_t est le type servant à coder les cartouches des blocs de mémoire (j'y viens). Donc, tu n'alloueras que des multiples de struct cartouche_t (si ton type s'appelle bien ainsi).

    L'idée est de conserver dans chaque bloc alloué, des informations qui te seront utiles ultérieurement. Pour te faciliter la tâche, tu peux déjà commencer par conserver la taille du bloc, et/ou sa taille (celà veut peut-être dire qu'une union peut traîner quelque part, à toi de voir).

    On suppose que l'on ne fait que de "petites allocations".

    Lors de la première allocation, tu fais appel à mmap. Tu coupes alors la zone en deux en conservant l'adresse de la place "libre" dans ta variable globale. Le cartouche de la place qui vient de se libérer doit aussi être initialisé correctement.

    Puis, au fur et à mesure que ton programme allouera, tu couperas ainsi l'espace libre... mais en faisant attention à une chose : lorsque tu libères de l'espace mémoire, le bloc qui vient de se libérer doit être inséré dans la liste des blocs libres (donc le cartouche doit aussi être modifié).

    Lorsque tu n'as plus de place, tu fais à nouveau appel à mmap pour obtenir plus d'espace mémoire.

    Il se pose aussi le problème de la fusion de blocs adjacents, mais là, c'est un autre débat.

    Les grandes lignes sont celles-ci : à toi d'adapter, voire de demander si tu veux que des points soient précisés.
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  3. #3
    Futur Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Salut InOCamlWeTrust et merci pour ta reponse!

    En fait j'ai considere les pages memoire comme des "super regions". En d'autres termes, je cree une premiere region de la taille d'une page et j'insere a l'interieur de cette region d'autres regions de taille inferieure.
    Pour des raisons de taille fixe, inutile de gerer le cas ou l'on veut allouer dans une region ou il n'y a plus assez d'espace, c'est assez trivial.
    Par contre, pour les regions de type illimite, j'ai decide d'ajouter un pointeur dans ma structure rgn qui pointe vers la prochaine region "super region" allouee si besoin il y a.

    Enfin, il me reste cette derniere partie a implementer. Mais pour l'instant ca me donne ca :

    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    /* rgn.c --- Routines d'allocation mémoire par régions.  */
     
    #include "rgn.h"
    #include <sys/mman.h>
    #include <unistd.h>
    #include <stdio.h>
     
    /* L'allocation de bas niveau se fait avec "mmap":
     
       ptr = mmap (NULL, nbytes,
                   PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)
     
       où nbytes doit être un multiple de la taille d'une page, i.e. un multiple
       de sysconf(_SC_PAGESIZE).  Cette mémoire peut être libérée plus tard
       avec "munmap".
       Voir "man mmap", "man munmap", et "man sysconf" pour de plus amples
       informations.  */
     
     
    /* Type d'un descripteur de région.  */
    struct rgn {
       int unlimited;
       int size;
       void *start;
       void *next;
       rgn *linked;
    };
     
    rgn *lastpage = NULL;
     
    void new_page()
    {
       lastpage = mmap(NULL, 4096, PROT_READ | PROT_WRITE , MAP_ANONYMOUS |
                  MAP_PRIVATE , -1 , 0);
       (*lastpage).unlimited = 0;
       (*lastpage).size = 4096 - sizeof(rgn);
       (*lastpage).start = lastpage;
       (*lastpage).next = lastpage + sizeof(rgn);
       (*lastpage).linked = NULL;
    }
     
    /* Crée une nouvelle région dont la taille maximale est "maxbytes", ou
       qui peut grandir sans limite si "maxbytes" est égal à  0.  */
    rgn  *rgn_new (size_t maxbytes)
    {
       rgn *r;
       /*Cas ou nous creons une region de taille illimitee :
         On va commencer par allouer une region a une nouvelle page. Si la region 
         atteint sa taille limite, alors on recreera une nouvelle region dans 
         rgn_alloc que l'on reliera a la premiere region via le pointeur "linked"*/
       if(maxbytes == 0) {  
          r = mmap(NULL, 4096, PROT_READ | PROT_WRITE , MAP_ANONYMOUS |
                   MAP_PRIVATE , -1 , 0);
          //On test si l'appel a mmap a reussi...
          if( r == MAP_FAILED) {
              //Si l'allocation a echoue, on imprime un message d'erreur
              perror(" Erreur mmap");
              }
     
          else  {
              //Sinon, on cree une region r dans l'espace alloue
              (*r).unlimited = 1;
              (*r).start = r;
              (*r).next = r + sizeof(rgn);
              (*r).linked = NULL; 
                }
       }          
     
       //Cas ou la taille de la region a allouer est inferieure a la taille d'une 
       //page : 
       if(maxbytes <= 4096 && maxbytes != 0) {
          // Si la derniere page allouee est egale a NULL :
          if(lastpage == NULL) {
             // On alloue une nouvelle page entiere:
             new_page();
             // Et on alloue un espace pour la region a l'interieur de cette page
             r = rgn_alloc(lastpage, maxbytes);
             // Si l'allocation a echoue
             if(r == NULL) {
                perror("Allocation failed");
             }
             //Sinon
             else {
                (*r).unlimited = 0;  
                (*r).size = maxbytes;
                (*r).start = r;
                (*r).next = r + sizeof(rgn);
                (*r).linked = NULL;
             } 
     
          }
     
          //Si la derniere page allouee n'est pas NULL :
          else {
             //S'il reste assez de place dans la derniere page allouee :
             if((*lastpage).size >= maxbytes + sizeof(rgn)) {
                r = rgn_alloc(lastpage, maxbytes);
                if(r == NULL) { perror("Allocation failed");}
                else { 
                   (*lastpage).size = (*lastpage).size - maxbytes - sizeof(rgn);
                   (*lastpage).next = (*lastpage).next + sizeof(rgn) + maxbytes;
     
                   (*r).unlimited = 0;  
                   (*r).size = maxbytes;
                   (*r).start = r;
                   (*r).next = r + sizeof(rgn);
                   (*r).linked = NULL; 
     
                }}
             //Sinon, on cree une autre page :
             else {
                // On alloue une nouvelle page entiere:
                new_page();
                // Et on alloue un espace pour la region a l'interieur de cette page
                r = rgn_alloc(lastpage, maxbytes);
                // Si l'allocation a echoue
                if(r != NULL) { perror("Allocation failed");}
                //Sinon
                else {
                   (*r).unlimited = 0;  
                   (*r).size = maxbytes;
                   (*r).start = r;
                   (*r).next = r + sizeof(rgn);
                   (*r).linked = NULL;
                } 
             }
          }
       }
     
       return r;    
    }
     
     
    /* Alloue un espace de "nbytes" dans la région "r" et renvoie son adresse,
       ou NULL si l'allocation échoue.  */
    void *rgn_alloc (rgn *r, size_t nbytes)
    {
       rgn *r2 = NULL;
     
     
       r2 = mmap((*r).next, nbytes, PROT_READ | PROT_WRITE , MAP_ANONYMOUS |
                 MAP_PRIVATE , -1 , 0);
     
       if(r2 != NULL) {
          (*r).size = (*r).size - nbytes - sizeof(rgn);
          (*r).next = (*r).size + nbytes + sizeof(rgn);      
     
       }
       return r2;
    }
     
     
    /* Libère l'espace occupé par la région "r".  */
    void  rgn_free (rgn *r)
    {
          munmap(r, (*r).size + sizeof(rgn));
    }
     
    #if 0
    /* On put implanter "malloc" au-dessus de nos régions.  */
     
    void *malloc (size_t nbytes)
    {
       rgn *r = rgn_new (nbytes + sizeof (rgn*));
       rgn **x = rgn_alloc (r, nbytes + sizeof (rgn*));
       *x = r;
       return x+1;
    }
     
    void free (void *ptr)
    {
       rgn **x = ptr;
       rgn_free (x[-1]);
    }
     
    #endif
     
    int main()
    {    
          new_page();
          rgn *r;
          r = rgn_new(45);
          printf("%i %i %p %p %p \n", (*r).unlimited, (*r).size, (*r).start , (*r).next ,
                (*r).linked);
          return 0;      
          }
     
    /* arch-tag: 64fdb756-d391-4f17-98b7-a5ecff6b652f */

  4. #4
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Je pense sincèrement que tu te prends trop la tête avec cette histoire de pages mémoire : ça complique ton code inutilement. En C, on s'en fout complètement d'être en plein milieu d'un page ou à-cheval de deux pages. Ce genre de considérations rentrent uniquement en jeu pour les gens qui font de la programmation système (et encore...).

    Ici, c'est très différent : ce que tu fais, c'est tout simplement créer une fonction d'allocation, ce qui relève du software.

    Si tu penses la mémoire comme un long rouleau extensible à coups d'appels à mmap de taille adéquate, je pense que tu pourras t'en sortir mieux que ça. Le seul problème ici, c'est que, à l'inverse de l'appel brk() qui étend littéralement le segment de données, mmap te permet de récupérer de nouvelles régions.

    Tu n'as pas besoin d'une "page" (si ce terme possède un sens...) pour y stocker toutes les autres : il te suffit d'une variable pointant vers un certain emplacement mémoire libre, lui-même contenant une variable pointant vers un deuxième emplacement libre (penser à conserver la taille), etc... Les blocs mémoire déjà alloués, tu les oublies ; de toutes façons, il ne te serviront que lors de la libération de l'espace mémoire (appel à free()) : c'est à ce moment-là que tu les introduiras dans la liste des blocs libres (en tête de liste par exemple, c'est ce qu'il y a de plus facile).

    Les cartouches doivent donc contenir uniquement la taille de la zone et l'adresse de la prochaine zone mémoire libre. Lorsque je dis "prochaine", je ne pense pas en termes d'adresse, mais en termes de liste chaînée.

    De plus, ton code est loin d'être portable ! Je viens de regarder la man page de mmap, et il n'est dit nulle part que le nombre d'octets doit être multiple de la taille des pages mémoire. La man page dit uniquement que c'est l'argument offset qui doit être, en général, un multiple de la taille d'une page... or ici, étant donné que tu utilises des pages anonymes, qui n'ont pas de correspondance avec un fichier, tu t'en moques de cet argument, et à la limite, tu pourrais mettre (off_t)0 si tu veux quelque chose de correct.

    Une autre chose : alloue uniquement par multiples de de sizeof(struct cartouche_t) (ou le bon type qui code les cartouches des blocs mémoire) : celà t'évitera d'avoir à faire des casts violents non conformes aux normes (ANSI entre autres). Tu perdras forcément des octets, mais tu ne peux pas faire autrement si tu veux quelque chose de portable un minimum. Si seulement tu savais tous les octets perdus par le malloc GNU... tu ne l'utiliserais même plus !

    Je suis plus que convaincu, pour avoir implanté un allocateur mémoire efficace (mais reposant sur une stratégie complètement différente), que la solution que je te propose est plus simple.

    Citation Envoyé par man mmap
    Nom

    mmap, munmap - Etablir / supprimer une projection en mémoire (map / unmap) des fichiers ou des périphériques.

    Synopsis

    #include <unistd.h>
    #include <sys/mman.h>

    #ifdef _POSIX_MAPPED_FILES

    void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);

    int munmap(void *start, size_t length);

    #endif

    Description

    La fonction mmap demande la projection en mémoire de length octets commencant à la position offset depuis un fichier (ou un autre objet) indiqué par le descripteur fd, de préférence à l'adresse pointée par start. Cette adresse n'est qu'une préférence, généralement 0. La véritable adresse où l'objet est projeté est renvoyée par la fonction mmap.

    L'argument prot indique la protection que l'on désire pour cette zone de mémoire, et ne doit pas entrer en conflit avec le mode d'ouverture du fichier. Les protections possibles sont les suivantes :

    PROT_EXEC
    On peut exécuter du code dans la zone mémoire.
    PROT_READ
    On peut lire le contenu de la zone mémoire
    PROT_WRITE
    On peut écrire dans la zone mémoire.
    PROT_NONE
    Le contenu de la zone memoire est inaccessible.

    Le paramètre flags indique le type de fichier projeté, les options de projection, et si les modifications faites sur la portion projetée sont privées ou doivent être partagées avec les autres références. Les options sont :

    MAP_FIXED
    N'utiliser que l'adresse indiquée. Si c'est impossible, mmap échouera. Si MAP_FIXED est spécifié start doit être un multiple de la longueur de page. Il est déconseillé d'utiliser cette option.
    MAP_SHARED
    Partager la projection avec tout autre processus utilisant l'objet. L'écriture dans la zone est équivalente à une écriture dans le fichier. Par contre ce dernier n'est pas nécessairement mis à jour tant qu'on n'a pas appelé msync(2) ou mumap(2) .
    MAP_PRIVATE
    Créer une projection privée, utilisant la méthode de copie à l'écriture. L'écriture dans la zone ne modifie pas le fichier.

    Vous devez indiquer soit MAP_SHARED, soit MAP_PRIVATE.

    Ces trois attributs sont décrits dans POSIX.1b (anciennement POSIX.4). Linux propose également les options MAP_DENYWRITE, MAP_EXECUTABLE MAP_NORESERVE, MAP_LOCKED MAP_GROWSDOWN et MAP_ANON(YMOUS).

    L'argument offset doit normalement être un multiple de la taille de page renvoyée par l'appel getpagesize(2) .

    L'appel système munmap détruit la projection dans la zone de mémoire spécifiée, et s'arrange pour que toute référence ultérieure à cette zone mémoire déclenche une erreur d'adressage. La projection est aussi automatiquement détruite lorsque le processue se termine. À l'inverse, la fermeture du descripteur de fichier ne supprime pas la projection.

    Valeur Renvoyée

    mmap renvoie un pointeur sur la zone de mémoire, s'il réussit. En cas d'échec il retourne MAP_FAILED (-1) et errno contient le code d'erreur.

    munmap renvoie 0 s'il réussit. En cas d'échec -1 est renvoyé et errno contient le code d'erreur (probablement EINVAL).
    Erreurs

    EBADF
    fd n'est pas un descripteur de fichier valide (et MAP_ANONYMOUS n'était pas précisé).
    EACCES
    On demande une projection privée MAP_PRIVATE mais fd n'est pas ouvert en lecture, ou on demande une projection partagée MAP_SHARED avec protection PROT_WRITE, mais fd n'est pas ouvert en lecture et ecriture (O_RDWR).
    EINVAL
    start ou length ou offset sont invalides. (par exemple : zone trop grande, ou non alignée sur une frontière de page).
    ETXTBSY
    MAP_DENYWRITE a été réclamé mais fd est ouvert en écriture
    EAGAIN
    Le fichier est verrouillé, ou trop de mémoire est verrouillée.
    ENOMEM
    pas assez de mémoire.

    L'accès à une zone de projection peut déclencher les signaux suivants :

    SIGSEGV
    Tentative d'écriture dans une zone en lecture seule
    SIGBUS
    Tentative d'accès à une portion de la zone qui ne correspond pas au fichier (par exemple après la fin du fichier, y compris lorsqu'un autre fichier l'a tronqué).

    Conformité

    SVr4, POSIX.1b (anciennement POSIX.4), BSD 4.4. SVr4 documente les codes d'erreur supplémentaires ENXIO et ENODEV.
    Voir Aussi
    getpagesize(2) , msync(2) , shm_open(2) , B.O. Gallmeister, POSIX.4, O'Reilly, pp. 119-124 et 365-369.
    N'hésite surtout pas à poser d'autres questions : c'est un sujet vaste et tout ne peut être dit en un seul post.
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  5. #5
    Futur Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    Merci encore une fois pour ta reponse!

    Je suis d'accord que le fait d'utiliser mmap sans se soucier des "pages" est vraiment plus simple.

    Le probleme, c'est que dans mon enonce, il est ecrit que :

    "mmap ne peut allouer que des multiples de pages (i.e. des mutilples de 4kb par exemple). Pour les regions de grande taille ou de taille illimitee, on peut sans autre dedier chaque page a une region..."

    Et mon prof est une sacree tete de mule, voila pourquoi je m'entete a suivre ses specifications meme si elles ont souvent l'air douteuses! D'ailleurs ca me pose pas mal de problemes niveau fragmentation...

  6. #6
    Membre éprouvé
    Avatar de InOCamlWeTrust
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 036
    Points : 1 284
    Points
    1 284
    Par défaut
    Oui, c'est une déviance courante des programmeurs C hardcore : certains ont des préjugés de ce type auxquels ils s'y attachent comme c'est pas permis... Le problème réside dans le fait que les technologies évoluent, et si ces idées étaient il y a 30 ans justifiées, aujourd'hui, dans la très grande majorité des cas, elles ne le sont plus, précisément parce que les choses changent.

    Pour revenir à nos moutons.

    Tu peux allouer effectivement par pages, ou multiples de pages : de toutes façons, la taille à passer en paramètre est une constante (dans ce cas-là), donc tu peux très bien laisser ta valeur, il n'y a pas de problème.

    Je reviens cependant à ce que je te disais plus haut : étant donné que chaque bloc contient en réalité un cartouche le décrivant, tu dois voir la mémoire comme un vecteur de cartouches. C'est ainsi beaucoup plus simple à programmer et surtout plus propre et portable. Lorsque tu alloues, tu dois donc retourner l'adresse du cartouche se trouvant juste après le cartouche contenant les informations effectives, si tu veux conserver les finformations lors de la libération (appel à free()).
    When Colt produced the first practical repeating handgun, it gave rise to the saying God created men, but Colt made them equal.

  7. #7
    Futur Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 14
    Points : 7
    Points
    7
    Par défaut
    C'est ce que je fais a l'aide d'un offset sur le debut de ma zone allouee. Tout a l'air de marcher correctement par rapport au jeu de test fourni par mon prof. Je crois que j'ai enfin fini de me prendre la tete dessus!

    En tout cas merci beaucoup a toi pour ta devotion et tes conseils!

Discussions similaires

  1. Réponses: 16
    Dernier message: 20/04/2006, 14h11
  2. [NetBeans] Probleme de Processus IDE(Gestion mémoire)
    Par sniperseb dans le forum NetBeans
    Réponses: 3
    Dernier message: 01/02/2006, 19h22
  3. Gestion session par default WSAD
    Par mlequim dans le forum Websphere
    Réponses: 3
    Dernier message: 17/11/2005, 15h16
  4. [JVM]Gestion mémoire : Bizarre
    Par elitost dans le forum Général Java
    Réponses: 2
    Dernier message: 28/09/2005, 20h34
  5. Consommation memoire par classe
    Par spartikis dans le forum C++
    Réponses: 5
    Dernier message: 25/07/2005, 16h42

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