код malloc в C
-
21-09-2019 - |
Вопрос
У меня есть блок кода, который, кажется, является кодом 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, если я правильно помню