Вопрос

У меня есть блок кода, который, кажется, является кодом malloc.Но когда я просматриваю код, у меня возникает ощущение, что части кода отсутствуют.Кто-нибудь знает, отсутствует ли какая-то часть функции?Делает malloc всегда объединять соседние фрагменты вместе?

int heap[10000];
void* malloc(int size) {
int sz = (size + 3) / 4;
int chunk = 0;
if(heap[chunk] > sz) {
    int my_size = heap[chunk];
    if (my_size < 0) {
      my_size = -my_size
    }
    chunk = chunk + my_size + 2;
    if (chunk == heap_size) { 
      return 0;
    }
}
Это было полезно?

Решение

Код, лежащий в основе malloc, безусловно, намного сложнее.Существует несколько стратегий.Одним из популярных кодов является dlmalloc библиотека.Более простой описан в K&R.

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

Код явно неполный (не все пути возвращают значение).Но в любом случае это не «настоящий» malloc.Вероятно, это попытка реализовать сильно упрощенную «модель» malloc.Подход, выбранный автором кода, не может привести к полезной практической реализации.

(И, кстати, стандартный параметр malloc имеет тип size_t, а не int).

Ну, одна ошибка в этом коде заключается в том, что он не возвращает указатель на данные.

Я подозреваю, что лучший подход к этому коду — [удалить].

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

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

Как уже упоминалось, есть проблемы с фрагментом кода.

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

malloc для динамически распределяемый Память.И это включает в себя sbrk, mmap, или, возможно, некоторые другие системные функции для Windows и/или других архитектур.Я не уверен, что ты int heap[10000] для, поскольку код слишком неполный.

Версия Effo имеет немного больше смысла, но в ней представлена ​​еще одна функция черного ящика. get_block, так что это не сильно помогает.

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

Насколько я понимаю, в 32-битной системе sizeof(ptr) = 4 байта:

extern block_t *block_head; // the real heap, and its address 
                            // is >= 0x80000000, see below "my_size < 0"
extern void *get_block(int index); // get a block from the heap 
                                   // (lead by block_head)
int heap[10000]; // just the indicators, not the real heap

void* malloc(int size) 
{
    int sz = (size + 3) / 4; // make the size aligns with 4 bytes,
                             // you know, allocated size would be aligned.
    int chunk = 0; // the first check point
    if(heap[chunk] > sz) { // the value is either a valid free-block size 
                           // which meets my requirement, or an 
                           // address of an allocated block
        int my_size = heap[chunk]; // verify size or address
        if (my_size < 0) { // it is an address, say a 32-bit value which 
                           // is >0x8000...., not a size. 
              my_size = -my_size // the algo, convert it
        }
        chunk = chunk + my_size + 2; // the algo too, get available 
                                     // block index
        if (chunk == heap_size) { // no free chunks left
           return NULL; // Out of Memory
        }
        void *block = get_block(chunk);
        heap[chunk] = (int)block;
        return block;
    }
    // my blocks is too small initially, none of the blocks 
    // will meet the requirement
    return NULL;
}

РЕДАКТИРОВАТЬ:Может ли кто-нибудь помочь объяснить алгоритм, то есть преобразование адреса -> my_size -> чанка?вы знаете, когда восстановление вызова, скажем, free(void *addr), он также будет использовать этот адрес -> my_size -> алгоритм фрагмента, чтобы соответствующим образом обновить кучу [кусок] после возврата блока в кучу.

Слишком мал, чтобы быть целой реализацией malloc

Загляните в исходники библиотеки C Visual Studio 6.0, там вы найдете реализацию malloc, если я правильно помню

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