Domanda

Quello che ho deciso di fare è

  • chiama malloc
  • copia il vecchio blocco nel nuovo blocco
  • libera il vecchio blocco
  • e restituisce il puntatore al nuovo blocco

Il codice qui sotto è quello che ho finora ... ma so che non è giusto ... qualsiasi aiuto per correggere il codice sarebbe molto apprezzato ...

Se hai bisogno di più codice di quello che ti ho fornito, ho un post precedente a questo che mostra tutto il codice. Sono nuovo, quindi c'è solo questo post e l'ultimo post che ho fatto. Grazie.

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;
}
È stato utile?

Soluzione

Idealmente, un realloc () vedrebbe semplicemente se c'è abbastanza memoria libera oltre il blocco corrente e, in tal caso, basta regolare le strutture dati dell'arena per espandere il blocco corrente sul posto. Questo elimina la costosa operazione di copia e riduce le possibilità di errore di allocazione. Questo è per aumentare le dimensioni. Per ridurre, dovresti essere in grado di farlo sempre sul posto, inviando il resto del blocco corrente al pool gratuito.

Effettuando un malloc / free, se hai 100K nell'arena con un singolo blocco da 60K allocato, la chiamata al tuo mm_realloc per regolare la dimensione a 50K fallirà.

Tuttavia, è una soluzione praticabile , almeno per un primo tentativo, quindi ecco come la implementerei:

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;
}

Una cosa che noterai che manca al tuo è che deve copiare solo abbastanza byte per il più piccolo dei blocchi vecchi e nuovi. Altrimenti rischi di scaricare core scaricandone uno.

Inoltre, il tuo loop non ha effettivamente copiato i dati, ha impostato ogni byte del blocco sul suo offset e ha perso il vecchio puntatore durante l'allocazione di quello nuovo, quindi il mio uso di newptr per tenerli separati.

Altri suggerimenti

Devi sapere quanto è grande il vecchio blocco e la nuova dimensione. Devi copiare la minore delle due dimensioni sul nuovo blocco.

Devi anche assicurarti di non distruggere (liberare) il vecchio blocco se malloc () fallisce - devi solo restituire 0.

Inoltre non è necessario moltiplicare la dimensione per 'sizeof (int)' in malloc (); stai davvero sovrallocando di un fattore 4 o più (in teoria, potrebbe essere solo un fattore 2, ma al giorno d'oggi poche persone usano compilatori a 16 bit).

Il punto di realloc è che tenta di unire il blocco di memoria con uno libero dietro quello, se possibile. Solo se non ce n'è uno libero, assegnerà nuova memoria, copierà tutto e libera il vecchio blocco.

Perché stai comunque scrivendo le tue routine di allocazione?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top