Skip to content

Instantly share code, notes, and snippets.

@trws
Created June 12, 2013 15:50
Show Gist options
  • Save trws/5766576 to your computer and use it in GitHub Desktop.
Save trws/5766576 to your computer and use it in GitHub Desktop.
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;
}
#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