Я разобрался, как написать realloc, но знаю, что код неправильный?

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

  •  08-07-2019
  •  | 
  •  

Вопрос

То, что я решил сделать, это

  • позвонить в Malloc
  • скопировать старый блок в новый блок
  • освободить старый блок
  • и верните указатель на новый блок

Код ниже - это то, что у меня есть на данный момент... но я знаю, что это неправильно... любая помощь по исправлению кода будет принята с благодарностью...

Если вам нужно больше кода, чем я предоставил, у меня есть сообщение до этого, в котором показан весь код.Я новичок, поэтому есть только этот пост и последний пост, который я написал.Спасибо.

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;
}
Это было полезно?

Решение

В идеале realloc() просто проверит, достаточно ли свободной памяти за пределами текущего блока, и, если да, просто скорректирует структуры данных арены, чтобы расширить текущий блок на месте.Это избавляет от дорогостоящей операции копирования и снижает вероятность сбоя выделения.Это для увеличения размера.Для сокращения вы всегда должны иметь возможность делать это на месте, отправляя остаток текущего блока обратно в свободный пул.

Выполняя malloc/free, если у вас на арене 100 КБ с выделенным одним блоком в 60 КБ, вызовите свой mm_realloc настроить размер на 50К не получится.

Однако это работоспособный решение, по крайней мере, для первой попытки, поэтому вот как бы я его реализовал:

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

Одна вещь, которую вы заметите, которой не хватает в вашей, это то, что она должна копировать только достаточно байтов для самый маленький из старого и нового блоков.В противном случае вы рискуете получить дамп ядра, переполнив один из них.

Кроме того, ваш цикл на самом деле не копирует данные, он устанавливает для каждого байта блока его смещение и теряет старый указатель при выделении нового, поэтому я использую newptr чтобы держать их отдельно.

Другие советы

Вам нужно знать, насколько велик старый блок, а также размер нового.Вам нужно скопировать меньший из двух размеров в новый блок.

Вы также должны убедиться, что вы не уничтожаете (освобождаете) старый блок в случае сбоя malloc() — вы просто возвращаете 0.

Вам также не нужно умножать размер на sizeof(int) в malloc();на самом деле вы превышаете выделение ресурсов в 4 или более раз (теоретически это может быть только в 2 раза, но в наши дни мало кто использует 16-битные компиляторы).

Суть realloc заключается в том, что он пытается объединить блок памяти со свободным блоком, находящимся за ним, если это возможно.Только если свободного нет, он выделит новую память, скопирует все и освободит старый блок.

Зачем вы вообще пишете свои собственные процедуры распределения?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top