Advertisement
Guest User

Untitled

a guest
Aug 27th, 2016
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.73 KB | None | 0 0
  1.  
  2. /*
  3.     Memory Arena: A big pool of memory allocated once to allocate your own arrays from.
  4.     Can guarantee contiguous memory for all data.
  5.  
  6.     Usage:
  7.  
  8.         MemoryArena *arena = new MemoryArena(size);
  9.         T *T_ptr = arena->alloc_1D<T>(len, init);
  10.         T **T_pptr = arena->alloc_2D<T>(len1, len2, init);
  11.  
  12.     Free all the memory using:
  13.  
  14.         delete arena;
  15.  
  16.     NOTE: WILL leave dangling pointers after destruction.
  17. */
  18.  
  19. struct MemoryArena {
  20.     size_t arena_size;
  21.     size_t current;
  22.     char *memory;
  23.  
  24.     // use a triple pointer to store a reference to each double pointer, so that
  25.     // the inner pointers can be deallocated
  26.     void ***memory_double_pointers;
  27.     size_t num_double_pointers;
  28.     size_t double_pointer_counter;
  29.  
  30.     MemoryArena(size_t size, int num_double_pointers) : arena_size(size), num_double_pointers(num_double_pointers) {
  31.         memory = new char[arena_size];
  32.         for (size_t i = 0; i < arena_size; i++)
  33.             memory[i] = 0;
  34.         current = 0;
  35.         printf("Allocate arena of size %d at 0x%p, memory byte alignment = %d\n", (int)size, memory, (int)((uintptr_t)memory & 15));
  36.  
  37.         double_pointer_counter = 0;
  38.         memory_double_pointers = new void**[num_double_pointers];
  39.         printf("Preparing to keep track of %d double pointers\n", (int)num_double_pointers);
  40.  
  41.     }
  42.     ~MemoryArena() {
  43.         printf("Destroying memory arena: %d double pointers and memory of size %d bytes\n", (int)double_pointer_counter, (int)arena_size);
  44.  
  45.         // destroying pointers from double pointers
  46.         for (size_t i = 0; i < num_double_pointers; i++) {
  47.             if (memory_double_pointers[i])
  48.                 delete[] memory_double_pointers[i];
  49.         }
  50.         // destryong double pointers
  51.         delete[] memory_double_pointers;
  52.  
  53.         // destroying contigious memory
  54.         delete[] memory;
  55.     }
  56.  
  57.     void* alloc_block(size_t block_size) {
  58.         size_t available_size = arena_size - current;
  59.  
  60.         if (available_size < block_size) {
  61.             printf("Not enough space to allocate block of size %d, only %d left\n", (int)block_size, (int)available_size);
  62.             return NULL;
  63.         } else {
  64.             size_t old_current = current;
  65.             current = current + block_size;
  66.             printf("Allocate %d bytes from arena, at index %d. Moving index to %d. %d left\n", (int)block_size, (int)old_current, (int)current, (int)(available_size-block_size));
  67.             return memory + old_current;
  68.         }
  69.     }
  70.  
  71.     // typename T need to have operator= overloaded
  72.     template <typename T>
  73.     T* alloc_1D(size_t len, T init) {
  74.         T *data = (T*)alloc_block(len*sizeof(T));
  75.         if (data) {
  76.             T *arr = data;
  77.             for (size_t i = 0; i < len; i++)
  78.                 arr[i] = init;
  79.             return arr;
  80.         } else {
  81.             return NULL;
  82.         }
  83.     }
  84.  
  85.     // For 2D arrays/double pointers we need to keep track of the
  86.     // double pointers themselves so that we can free the memory used
  87.     // for the inner pointers
  88.     // these are stored in void ***memory_double_pointers
  89.     template <typename T>
  90.     T** alloc_2D(size_t len1, size_t len2, T init) {
  91.         // allocate 1D block of contiguous memory
  92.         T *data = (T*)alloc_block(len1*len2*sizeof(T));
  93.  
  94.         if (data) {
  95.             T** arr = new T*[len1];
  96.             memory_double_pointers[double_pointer_counter++] = (void**)arr;
  97.  
  98.             for (size_t i = 0; i < len1; i++) {
  99.                 arr[i] = data + len2*i;
  100.                 for (size_t j = 0; j < len2; j++) {
  101.                     arr[i][j] = init;
  102.                 }
  103.             }
  104.             return arr;
  105.         } else {
  106.             return NULL;
  107.         }
  108.     }
  109. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement