#include #include struct XX { int a, b; char c; }; //typedef char storage_t; //typedef short storage_t; typedef int storage_t; //typedef long long storage_t; //typedef long double storage_t; //typedef struct { char c[9]; } __attribute__((packed)) storage_t; #define __align_up(x, y) (((x) + (y)-1) / (y)) #define __align_down(x, y) ((x) / (y)) #define __align_storage_size(x) __align_up(x, sizeof(storage_t)) #define __align_X_size(x) __align_down(sizeof(storage_t), x) #define align_storage_units(nr, X) \ __align_up(((nr) * __align_storage_size(X)), __align_X_size(X)) static inline int resize_storage(int nr_xx, storage_t **storage) { int storage_nr = align_storage_units(nr_xx, sizeof(void *)); int storage_bytes = storage_nr * sizeof(storage_t); storage_t *s = (storage_t *)realloc(*storage, storage_bytes); if (!s) return 0; *storage = s; return storage_nr; } static inline void free_storage(storage_t **storage) { free(*storage); *storage = NULL; } static inline void **ptr_storage(storage_t *storage, int i) { return (void **)storage + i; } static inline void put_to_storage(storage_t *storage, int i, void *arg) { *(ptr_storage(storage, i)) = arg; } static inline void *get_from_storage(storage_t *storage, int i) { return *(ptr_storage(storage, i)); } int main(void) { int i; struct XX xx[10]; int nr_xx = sizeof(xx) / sizeof(xx[0]); /* to test */ for (i = 0; i < nr_xx; i++) { xx[i].a = i + 1; } storage_t *dd = NULL; int nr_dd = resize_storage(nr_xx, &dd); if (!nr_dd || !dd) { perror(""); return -1; } printf("storage: %d units, %d bytes at %p\n", nr_dd, nr_dd * sizeof(*dd), dd); /* assign */ for (i = 0; i < nr_xx; i++) { put_to_storage(dd, i, &xx[i]); } /* test */ for (i = 0; i < nr_xx; i++) { struct XX *pxx = (struct XX *)get_from_storage(dd, i); #if 1 typedef unsigned long ptr_t; ptr_t xdd = (ptr_t)dd + sizeof(ptr_t) * i; printf("dd[%d.%d)]: %p: a = %d\n", (int)((xdd - (ptr_t)dd) / sizeof(storage_t)), (int)((xdd - (ptr_t)dd) % sizeof(storage_t)), pxx, pxx->a); #else #define verify(_x) \ printf("%d: (%s) %d %c= %d\n", \ i, #_x, xx[i]._x, (xx[i]._x != pxx->_x)?'!':'=',pxx->_x) verify(a); #undef verify #endif } /* cleanup */ printf("freeing %p\n", dd); resize_storage(0, &dd); return 0; }