Created
August 6, 2017 19:04
-
-
Save ofdouglas/2f1effa44f48b68c896c1a42f1ced223 to your computer and use it in GitHub Desktop.
Dynamic allocation from a statically allocated pool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stddef.h> | |
#include "public.h" | |
#include "assert.h" | |
#define NUM_FOOS 4 | |
int main (void) | |
{ | |
foo_module_init(NUM_FOOS); | |
struct foo * foo_handles[NUM_FOOS + 1]; | |
/* Show that we can succesfully allocate NUM_FOOS objects, and that additional | |
* allocation attempts will fail safely. | |
*/ | |
for (int i = 0; i < NUM_FOOS + 1; i++) { | |
foo_handles[i] = foo_allocate(); | |
printf("foo_handles[%d] allocate %s\n", | |
i, foo_handles[i] ? "OK" : "FAILED"); | |
} | |
/* Show that we can succesfully free an object and re-use that memory. | |
*/ | |
foo_free(foo_handles[0]); | |
foo_handles[NUM_FOOS] = foo_allocate(); | |
assert(foo_handles[NUM_FOOS]); | |
foo_configure(foo_handles[0], 1, 2); | |
printf("foo result = %d\n", foo_do_stuff(foo_handles[0])); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "public.h" | |
#include <stdlib.h> | |
#include <assert.h> | |
// Private implementation of foo | |
struct foo { | |
int x; | |
int y; | |
/* Used to maintain the free list. If you won't ever free foo objects, you | |
* could remove this item and allocate by incrementing an index into the | |
* free list... | |
*/ | |
struct foo * next; | |
}; | |
// Pointer to statically allocated pool of foo objects | |
static struct foo * free_list; | |
/* Make the foo module ready for use. This must be called exactly once, before | |
* any functions in the foo module are used. | |
*/ | |
void foo_module_init(size_t num_foos) | |
{ | |
free_list = malloc(num_foos * sizeof(struct foo)); | |
assert(free_list); | |
for (int i = 0; i < num_foos - 1; i++) | |
free_list[i].next = &free_list[i+1]; | |
} | |
/* Allocate and return a foo if possible; else return NULL. | |
*/ | |
struct foo * foo_allocate(void) | |
{ | |
struct foo * f = free_list; | |
if (f != NULL) | |
free_list = f->next; | |
return f; | |
} | |
/* Deallocate a foo. | |
*/ | |
void foo_free(struct foo * f) | |
{ | |
if (f == NULL) | |
return; | |
f->next = free_list; | |
free_list = f; | |
} | |
void foo_configure(struct foo * f, int x, int y) | |
{ | |
if (f == NULL) | |
return; | |
f->x = x; | |
f->y = y; | |
} | |
/* In a real application this would do something interesting. | |
*/ | |
int foo_do_stuff(struct foo * f) | |
{ | |
return f->x + f->y; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __PUBLIC_H | |
#define __PUBLIC_H | |
#include <stddef.h> | |
// Opaque type | |
struct foo; | |
void foo_module_init(size_t num_foos); | |
struct foo * foo_allocate(void); | |
void foo_free(struct foo * f); | |
void foo_configure(struct foo * f, int x, int y); | |
int foo_do_stuff(struct foo * f); | |
#endif // __PUBLIC_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment