dm_alloc Q1-6
This commit is contained in:
parent
d524b90c2b
commit
8c2bc954a6
159
dm_alloc/allocateur_blocs_taille_fixe.c
Normal file
159
dm_alloc/allocateur_blocs_taille_fixe.c
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
// #include <stdbool.h>
|
||||||
|
// #include <stdint.h>
|
||||||
|
// #include <stdlib.h>
|
||||||
|
|
||||||
|
// const uint64_t HEAP_SIZE = 32;
|
||||||
|
// const uint64_t BLOCK_SIZE = 8;
|
||||||
|
// uint64_t heap[HEAP_SIZE];
|
||||||
|
|
||||||
|
// void init_heap() {
|
||||||
|
// heap[0] = 2;
|
||||||
|
// for (uint64_t i = 1; i + BLOCK_SIZE <= HEAP_SIZE; i += BLOCK_SIZE) {
|
||||||
|
// heap[i] = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool is_free(uint64_t i) { return !heap[i - 1]; }
|
||||||
|
// void set_free(uint64_t i) { heap[i - 1] = 0; }
|
||||||
|
// void set_used(uint64_t i) { heap[i - 1] = 1; }
|
||||||
|
|
||||||
|
// uint64_t *malloc_ui(uint64_t size) {
|
||||||
|
// for (uint64_t i = 2; i - 1 + BLOCK_SIZE <= HEAP_SIZE; i += BLOCK_SIZE) {
|
||||||
|
// if (is_free(i)) {
|
||||||
|
// set_used(i);
|
||||||
|
// if (i > heap[0]) {
|
||||||
|
// heap[0] = i;
|
||||||
|
// }
|
||||||
|
// return &heap[i];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return NULL;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void free_ui(uint64_t *p) {
|
||||||
|
// uint64_t i = p - heap;
|
||||||
|
// heap[i - 1] = 0;
|
||||||
|
// if (i == heap[0]) {
|
||||||
|
// while (is_free(heap[0]) && heap[0] > 2) {
|
||||||
|
// heap[0] -= BLOCK_SIZE;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Comme uint64_t est un peu pénible à taper, on utilise
|
||||||
|
// un typedef :
|
||||||
|
typedef uint64_t ui;
|
||||||
|
|
||||||
|
#define HEAP_SIZE 32
|
||||||
|
|
||||||
|
ui heap[HEAP_SIZE];
|
||||||
|
|
||||||
|
// Cette fonction convertit un pointeur (qui doit être issu de
|
||||||
|
// malloc_ui) en un indice dans le tableau heap.
|
||||||
|
// Vous en aurez besoin pour écrire les différentes versions
|
||||||
|
// de free_ui (juste un appel au début, ensuite on ne manipule plus
|
||||||
|
// que des indices), mais il est complètement normal de ne pas
|
||||||
|
// comprendre comment elle fonctionne : c'est de l'arithmétique des
|
||||||
|
// pointeurs, qui est hors programme.
|
||||||
|
ui heap_index(ui *p) { return p - heap; }
|
||||||
|
|
||||||
|
// Cette fonction initialise le tas à une valeur particulière, que
|
||||||
|
// vous avez peu de chance d'utiliser par hasard. Cela nous
|
||||||
|
// permettra en pratique de repérer les cases dont la valeur n'a
|
||||||
|
// jamais été modifiée quand on affiche le contenu du tas.
|
||||||
|
// Elle est destinée à être appelée une unique fois, tout au début
|
||||||
|
// de l'exécution du programme.
|
||||||
|
void pre_initialize_heap(void) {
|
||||||
|
for (ui i = 0; i < HEAP_SIZE; i++) {
|
||||||
|
heap[i] = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// La fonction suivante affiche le contenu du tas. Les cases
|
||||||
|
// identifiées comme n'ayant jamais été modifiées sont affichées
|
||||||
|
// de manière particulière.
|
||||||
|
void print_heap(void) {
|
||||||
|
for (ui i = 0; i < HEAP_SIZE; i++) {
|
||||||
|
ui x = heap[i];
|
||||||
|
if (x == 0xFFFFFFFF) {
|
||||||
|
printf("... ");
|
||||||
|
} else {
|
||||||
|
printf("%3" PRIu64 " ", x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_memory(ui *p, ui size, ui value) {
|
||||||
|
for (ui i = 0; i < size; i++) {
|
||||||
|
p[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ui block_size = 8;
|
||||||
|
|
||||||
|
void init_heap(void) {
|
||||||
|
heap[0] = 2;
|
||||||
|
for (ui i = 1; i + block_size <= HEAP_SIZE; i += block_size) {
|
||||||
|
heap[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_free(uint64_t i) { return !heap[i - 1]; }
|
||||||
|
|
||||||
|
void set_free(uint64_t i) { heap[i - 1] = 0; }
|
||||||
|
|
||||||
|
void set_used(uint64_t i) { heap[i - 1] = 1; }
|
||||||
|
|
||||||
|
uint64_t *malloc_ui64(uint64_t size) {
|
||||||
|
for (ui i = 2; i - 1 + block_size <= HEAP_SIZE; i += block_size) {
|
||||||
|
if (is_free(i)) {
|
||||||
|
set_used(i);
|
||||||
|
if (i >= heap[0]) {
|
||||||
|
heap[0] = i + block_size;
|
||||||
|
}
|
||||||
|
return &heap[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_ui64(uint64_t *p) {
|
||||||
|
// Indice du bloc à libérer
|
||||||
|
uint64_t i = heap_index(p);
|
||||||
|
heap[i - 1] = 0;
|
||||||
|
if (i + block_size == heap[0]) {
|
||||||
|
while (heap[0] > 2 && is_free(heap[0] - block_size)) {
|
||||||
|
heap[0] -= block_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
pre_initialize_heap();
|
||||||
|
|
||||||
|
// Pour tester, une fois que les fonctions sont implémentées
|
||||||
|
init_heap();
|
||||||
|
uint64_t *p1 = malloc_ui64(6);
|
||||||
|
uint64_t *p2 = malloc_ui64(3);
|
||||||
|
set_memory(p1, 6, 42);
|
||||||
|
set_memory(p2, 3, 52);
|
||||||
|
print_heap();
|
||||||
|
uint64_t *p3 = malloc_ui64(5);
|
||||||
|
set_memory(p3, 5, 62);
|
||||||
|
print_heap();
|
||||||
|
free_ui64(p2);
|
||||||
|
print_heap();
|
||||||
|
free_ui64(p3);
|
||||||
|
print_heap();
|
||||||
|
free_ui64(p1);
|
||||||
|
print_heap();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
76
dm_alloc/allocateur_lineaire.c
Normal file
76
dm_alloc/allocateur_lineaire.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Comme uint64_t est un peu pénible à taper, on utilise
|
||||||
|
// un typedef :
|
||||||
|
typedef uint64_t ui;
|
||||||
|
|
||||||
|
#define HEAP_SIZE 32
|
||||||
|
|
||||||
|
ui heap[HEAP_SIZE];
|
||||||
|
|
||||||
|
// Cette fonction initialise le tas à une valeur particulière, que
|
||||||
|
// vous avez peu de chance d'utiliser par hasard. Cela nous
|
||||||
|
// permettra en pratique de repérer les cases dont la valeur n'a
|
||||||
|
// jamais été modifiée quand on affiche le contenu du tas.
|
||||||
|
// Elle est destinée à être appelée une unique fois, tout au début
|
||||||
|
// de l'exécution du programme.
|
||||||
|
void pre_initialize_heap(void) {
|
||||||
|
for (ui i = 0; i < HEAP_SIZE; i++) {
|
||||||
|
heap[i] = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// La fonction suivante affiche le contenu du tas. Les cases
|
||||||
|
// identifiées comme n'ayant jamais été modifiées sont affichées
|
||||||
|
// de manière particulière.
|
||||||
|
void print_heap(void) {
|
||||||
|
for (ui i = 0; i < HEAP_SIZE; i++) {
|
||||||
|
ui x = heap[i];
|
||||||
|
if (x == 0xFFFFFFFF) {
|
||||||
|
printf("... ");
|
||||||
|
} else {
|
||||||
|
printf("%3" PRIu64 " ", x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_memory(ui *p, ui size, ui value) {
|
||||||
|
for (ui i = 0; i < size; i++) {
|
||||||
|
p[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_ui64(uint64_t *p) {}
|
||||||
|
|
||||||
|
void init_heap() { heap[0] = 1; }
|
||||||
|
|
||||||
|
uint64_t *malloc_ui64(uint64_t size) {
|
||||||
|
if (heap[0] + size > HEAP_SIZE) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
heap[0] += size;
|
||||||
|
return &heap[heap[0] - size];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
pre_initialize_heap();
|
||||||
|
|
||||||
|
// Pour tester, une fois que les fonctions sont implémentées
|
||||||
|
init_heap();
|
||||||
|
uint64_t *p1 = malloc_ui64(6);
|
||||||
|
uint64_t *p2 = malloc_ui64(5);
|
||||||
|
set_memory(p1, 6, 42);
|
||||||
|
set_memory(p2, 5, 52);
|
||||||
|
free_ui64(p2);
|
||||||
|
free_ui64(p1);
|
||||||
|
|
||||||
|
print_heap();
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user