так что я хочу создать свой собственный malloc. Мне дали библиотеку, которая дает мне мою собственную функцию sbrk () для увеличения кучи, которая в основном использует malloc () для создания «симулированной» виртуальной памяти.
В любом случае, я столкнулся с проблемами при реализации моей функции free ()метод. Это приводит к путанице указателей и ставит под сомнение все существование вселенной. Таким образом, я создаю пример кода.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
size_t *seg_lists[4] = {NULL};
// Allocate two memory blocks of size 2
// First 8 bytes hold the size
// the last 2 8 bytes partition hold the data
void *mem1 = malloc(3*sizeof(size_t));
void *mem2 = malloc(3*sizeof(size_t));
// Set size fields
*(size_t *)mem1 = 2;
*(size_t *)mem2 = 2;
// Move pointers to start of body
mem1 = (size_t *)mem1 + 1;
mem2 = (size_t *)mem2 + 1;
// Set data to body of mem1
size_t* mem1_first = (size_t *)mem1;
size_t* mem1_second = (size_t *)mem1 + 1;
*mem1_first = 100;
*mem1_second = 200;
// Set data to body of mem2
size_t* mem2_first = (size_t *)mem2;
size_t* mem2_second = (size_t *)mem2 + 1;
*mem2_first = 300;
*mem2_second = 400;
// Output bodies of mem1 and mem2
printf("mem1=[%zu|%zu|%zu]\n", *((size_t *)mem1-1), *mem1_first, *mem1_second);
printf("mem2=[%zu|%zu|%zu]\n", *((size_t *)mem2 - 1), *mem2_first, *mem2_second);
// We first free mem2 and add it to the seg_list with index 1
size_t *head = seg_lists[1];
seg_lists[1] = mem2;
*(size_t *)mem2 = (size_t)head;
// We now want to free mem1 and add it to the list.
// I.e. we set the head to mem1 and the first 8 bytes of the body of
// mem2 to the address of mem1
head = seg_lists[1];
seg_lists[1] = mem1;
*(size_t *)mem1 = (size_t)head;
// Follow first entry in seg_lists[1] and print the 2nd 8 bytes of it's body
size_t *first = *seg_lists[1];
printf("*first=%zu\n", *(first+1));
}
Итак, сначала я создаю два блока памяти размером 2. Т.е. они могут содержать до 16 байтов данных. Первые 8 байтов используются для хранения размера. Так это выглядит так:
mem1=[2|100|200]
mem2=[2|300|400]
Далее я хочу освободить оба блока памяти. Адрес следующего свободного блока должен быть сохранен в первых 8 байтах тела предыдущего блока, тогда как последний должен всегда указывать на NULL.
После освобождения mem1
мы хотим, чтобы seg_list[1]
указывал наадрес mem1
и первые 8 байтов тела mem1
для хранения NULL
. После освобождения mem2
мы хотим, чтобы seg_list[1]
указывал на адрес mem2
, а первые 8 байтов тела mem2
должны содержать адрес mem1
.
Теперь ясделал "сохранить адрес X
в первых 8 байтах тела Y
", фактически сохранив шестнадцатеричное значение адреса в этих байтах.
Теперь кто-то продолжал пытаться сказать мне, что это неправильно,Я не должен этого делать. Я не могу сохранить адрес в качестве значения, но не понимаю, почему не смог. Это, очевидно, работает, и для меня память просто хранит данные. Адрес - это шестнадцатеричное значение, которое я могу сохранить как обычные данные, а затем просто обработать его, как я хочу.
Так что, на самом деле, плохо, что я здесь делаю? Разве я не должен сохранять адрес как «простые данные»?