Eu descobri como escrever realloc, mas sei que o código não é certo?

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

  •  08-07-2019
  •  | 
  •  

Pergunta

O que eu decidi fazer é

  • chamada malloc
  • copiar o bloco antigo para o novo bloco
  • liberar o bloco de idade
  • e retornar o ponteiro para o novo bloco

O código abaixo é o que eu tenho até agora ... mas eu sei que não está certo ... qualquer ajuda para corrigir o código seria muito apreciada ...

Se precisar de mais código do que o que eu tenho desde que eu tenho um post anterior a esta que mostra todo o código. Eu sou novo para que haja apenas este post eo último post eu fiz. Obrigado.

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;
}
Foi útil?

Solução

Idealmente, um realloc() simplesmente ver se há memória livre suficiente para além do bloco atual e, em caso afirmativo, basta ajustar as estruturas de dados arena para expandir o bloco atual no local. Isso se livrar da operação de cópia caro e reduz as chances de falha de alocação. Isso é para aumentar o tamanho. Para reduzir, você deve ser capaz de fazê-lo no local sempre, enviando o restante da parte de trás do bloco atual para a piscina livre.

Ao fazer um malloc / livre, se você tiver 100K com um único bloco 60K alocados a arena, chamando seu mm_realloc para ajustar o tamanho de 50K irá falhar.

No entanto, é a viável solução, pelo menos por uma primeira tentativa, então aqui está como eu iria implementá-lo:

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

Uma coisa que você vai perceber que está faltando o seu é que tem que copiar apenas o suficiente bytes para os dos antigos e novos blocos. Caso contrário, corre o risco de descarregar um core pelo transbordamento um deles.

Não

Além disso, o seu ciclo chegou a copiar os dados, definir cada byte do bloco para o seu deslocamento, e perdeu o ponteiro de idade quando alocar o novo, daí o meu uso de newptr mantê-los separados.

Outras dicas

Você precisa saber o quão grande o bloco de idade é, assim como o novo tamanho. Você tem que copiar o menor dos dois tamanhos sobre o novo bloco.

Você também tem que garantir que você não destruir (livre) do bloco velho se o malloc () falhar -. Você acabou de retornar 0

Você também não precisa multiplicar o tamanho de 'sizeof (int)' no malloc (); você está realmente overallocating por um fator de 4 ou mais (em teoria, pode ser apenas um fator de 2, mas poucas pessoas usam os compiladores de 16 bits nos dias de hoje).

O ponto de realloc é que ele tenta mesclar o bloco de memória com um livre por trás disso, se possível. Só se não houver um livre, ele vai alocar nova memória, copiar tudo mais, e libera o bloco de idade.

Por que você está escrevendo suas próprias rotinas de alocação de qualquer maneira?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top