Eu descobri como escrever realloc, mas sei que o código não é certo?
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;
}
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?