J'ai compris comment écrire realloc, mais je sais que le code n'est pas correct?

StackOverflow https://stackoverflow.com/questions/1641067

  •  08-07-2019
  •  | 
  •  

Question

Ce que j'ai décidé de faire est

  • appelez malloc
  • copier l'ancien bloc sur le nouveau
  • libérer l'ancien bloc
  • et retournez le pointeur sur le nouveau bloc

Le code ci-dessous correspond à ce que j’ai jusqu’à présent ... mais je sais que ce n’est pas correct ... toute aide pour le réparer serait grandement appréciée ...

Si vous avez besoin de plus de code que ce que j’ai fourni, j’ai publié un article avant celui-ci qui montre tout le code. Je suis nouveau donc il n'y a que ce post et le dernier post que j'ai fait. Merci.

void *mm_realloc(void *ptr, size_t size)
{
int i, p = *ptr;

 // make a call to malloc to find space
 //allocate memory

 ptr = malloc(size_t*sizeof(int));

 //copying old block to new block
 if(ptr!=NULL)
     for(i=0 ; i<size_t ; i++) 
     {
     *(ptr+i) = i;
     }

//freeing old block
free(ptr);

//return pointer to new block
return *ptr;
}
Était-ce utile?

La solution

Idéalement, un realloc () devrait simplement voir s'il y a suffisamment de mémoire libre au-delà du bloc actuel et, si tel est le cas, il suffit d'ajuster les structures de données d'arène pour développer le bloc actuel sur place. Cela supprime l'opération de copie coûteuse et réduit les risques d'échec de l'allocation. C'est pour augmenter la taille. Pour réduire, vous devriez pouvoir toujours le faire sur place, en renvoyant le reste du bloc actuel au pool libre.

En faisant malloc / free, si vous avez 100 Ko dans l'arène avec un seul bloc de 60 Ko alloué, appeler votre mm_realloc pour ajuster la taille à 50 Ko échouera.

Cependant, il s’agit d’une solution réalisable , du moins pour une première tentative, voici donc comment je l’implémenterais:

void *mm_realloc (void *ptr, size_t size) {
    int minsize;
    void *newptr;

    // Allocate new block, returning NULL if not possible.

    newptr = malloc (size);
    if (newptr == NULL) return NULL;

    // Don't copy/free original block if it was NULL.

    if (ptr != NULL) {
        // Get size to copy - mm_getsize must give you the size of the current block.
        // But, if new size is smaller, only copy that much. Many implementations
        // actually reserve the 16 bytes in front of the memory to store this info, e.g.,
        // +--------+--------------------------------+
        // | Header | Your data                      |
        // +--------+--------------------------------+
        //           ^
        //           +--- this is your pointer.
        // <- This is the memory actually allocated ->

        minsize = mm_getsize (ptr);
        if (size < minsize)
           minsize = size;

        // Copy the memory, free the old block and return the new block.

        memcpy (newptr, ptr, minsize);
        free (ptr)
    }

    return newptr;
}

Une chose que vous remarquerez qui manque au vôtre, c'est qu'il ne doit copier que suffisamment d'octets pour le plus petit des anciens et des nouveaux blocs. Sinon, vous risquez le dépotoir en faisant déborder l’un d’eux.

De plus, votre boucle n'a pas copié les données, elle a mis chaque octet du bloc sur son offset et a perdu l'ancien pointeur lors de l'allocation du nouveau, d'où mon utilisation de newptr pour les garder séparés.

Autres conseils

Vous devez connaître la taille de l'ancien bloc ainsi que sa nouvelle taille. Vous devez copier la plus petite des deux tailles sur le nouveau bloc.

Vous devez également vous assurer que vous ne détruisez pas (gratuitement) l'ancien bloc si le malloc () échoue - vous ne renvoyez que 0.

Vous n'avez pas non plus besoin de multiplier la taille par 'sizeof (int)' dans le malloc (); vous êtes vraiment en train de suraligner par un facteur de 4 ou plus (en théorie, ce pourrait être un facteur de 2, mais peu de gens utilisent des compilateurs 16 bits de nos jours).

Le point essentiel de realloc est qu'il tente de fusionner le bloc de mémoire avec un bloc libre derrière, si possible. Ce n'est que s'il n'y en a pas un gratuit qu'il va allouer une nouvelle mémoire, tout copier et libérer l'ancien bloc.

Pourquoi écrivez-vous quand même vos propres routines d’allocation?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top