Created
June 12, 2013 15:50
-
-
Save trws/5766576 to your computer and use it in GitHub Desktop.
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
void *alloc2d(size_t item_size, size_t len1, size_t len2){ | |
void ** arr = (void**)malloc(len1*sizeof(void*)); | |
for(int i=0; i<len1; i++){ | |
arr[i] = malloc(len2*item_size); | |
} | |
return arr; | |
} |
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 <stdint.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <errno.h> | |
#include <string.h> | |
typedef struct { | |
uint64_t ind_size; | |
void **ind_start; | |
uint64_t arr_size; | |
void *arr_start; | |
void **current_ind; | |
int sentinel; | |
} dopev; | |
void md_malloc(dopev &d) | |
{ | |
dopev *array = (dopev *)malloc(d.arr_size + d.ind_size + sizeof(dopev));//allocate | |
if(array == NULL) { | |
errno = ENOMEM; | |
perror("md_alloc failed, malloc returned NULL:"); | |
exit(ENOMEM); | |
} | |
array[0] = d; | |
d.ind_start = (void **)(array + 1); | |
d.current_ind = d.ind_start; | |
d.arr_start = (void *)(((char *)d.ind_start) + d.ind_size); | |
//fprintf(stderr, "allocated %p\n", array); | |
} | |
void *md_map(int dims, uint64_t item_size, const uint64_t counts[], dopev &d, char *arr, void **ind) | |
{ | |
if(dims == 1) { | |
return arr; | |
} else { | |
uint64_t dim_prod = item_size; | |
for(int i = 1; i < dims; ++i) { | |
dim_prod *= counts[i]; | |
} | |
void **outer = d.current_ind; | |
d.current_ind += counts[0]; | |
//fprintf(stderr, "ind taking %llu, dims=%d ind=%p, ind_start=%p, arr=%p, arr_start=%p\n", (uint64_t)sizeof(void *) * counts[0], dims, ind, d.ind_start, arr, d.arr_start); | |
for(int i = 0; i < counts[0]; ++i) { | |
outer[i] = md_map(dims - 1, item_size, counts + 1, d, arr + (dim_prod * i), d.current_ind); | |
} | |
return outer; | |
} | |
} | |
uint64_t ind_size(int dims, const uint64_t counts[]) | |
{ | |
if(dims > 1) { | |
uint64_t size = counts[0]; | |
size += counts[0] * ind_size(dims - 1, counts + 1); | |
return size; | |
} else { | |
return 0; | |
} | |
} | |
void *md_alloc(int dims, uint64_t item_size, const uint64_t counts[], int initialize, int val) | |
{ | |
if(counts == NULL) { | |
errno = EINVAL; | |
perror("md_alloc failed, a NULL sizes list is not allowd:"); | |
exit(EINVAL); | |
} | |
dopev dope = {.sentinel = 0xDEADBEEF}; | |
dope.arr_size = item_size; | |
for(int i = 0; i < dims; ++i) { //calculate complete size | |
dope.arr_size *= counts[i]; | |
} | |
dope.ind_size = sizeof(void *)*ind_size(dims, counts); //accounts for 1d arrays | |
md_malloc(dope); | |
if(initialize) { | |
memset(dope.arr_start, val, dope.arr_size); | |
} | |
void *arr = md_map(dims, item_size, counts, dope, (char *)dope.arr_start, dope.ind_start); | |
//fprintf(stderr, "ind_size=%llu, ind used=%llu\n", dope.ind_size, (uint64_t)dope.current_ind - (uint64_t)dope.ind_start); | |
return arr; | |
} | |
void md_free(void *ptr) | |
{ | |
dopev *arr = ((dopev *)ptr) - 1; | |
if(ptr == NULL || arr[0].sentinel != 0xDEADBEEF) { | |
errno = EINVAL; | |
perror("md_free failed, a NULL pointer or a non-md array specified:"); | |
throw; | |
exit(EINVAL); | |
} | |
free(arr); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment