Я понял, как написать realloc, но я знаю, что код не так? - PullRequest
1 голос
/ 29 октября 2009

Я решил сделать

  • вызов 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;
}

Ответы [ 3 ]

2 голосов
/ 29 октября 2009

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

Делая malloc / free, если у вас есть 100K на арене с выделенным одиночным блоком 60K, вызов вашего mm_realloc для настройки размера до 50K не удастся.

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

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, чтобы держать их отдельно .

1 голос
/ 29 октября 2009

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

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

1 голос
/ 29 октября 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...