From time to time I use the following code for generating a matrix style datastructure
typedef double myType;
typedef struct matrix_t{ |Compilation started at Mon Apr 5 02:24:15
myType **matrix; |
size_t x; |gcc structreaderGeneral.c -std=gnu99 -lz
size_t y; |
}matrix; |Compilation finished at Mon Apr 5 02:24:15
|
|
matrix alloc_matrix(size_t x, size_t y){ |
if(0) |
fprintf(stderr,"\t-> Alloc matrix with dim (%lu,%lu) byteprline=%lu bytetotal:%l\|
u\n",x,y,y*sizeof(myType),x*y*sizeof(myType)); |
|
myType **m = (myType **)malloc(x*sizeof(myType **)); |
for(size_t i=0;i<x;i++) |
m[i] =(myType *) malloc(y*sizeof(myType *)); |
|
matrix ret; |
ret.x=x; |
ret.y=y; |
ret.matrix=m; |
return ret; |
}
And then I would change my typedef accordingly if I needed a different kind of type for the entries in my matrix.
Now I need 2 matrices with different types, an easy solution would be to copy/paste the code, but is there some way to do a more generic implementation.
Thanks
edit: I should clarify that its in c not c++. Sorry for not making that clear.
In C? Messy, but possible with macro magic. (You're getting to the point where C++ is a better choice, BTW).
#define DECL_MATRIX(type,name) \
typedef struct matrix_##type##_t { \
type **matrix; \
size_t x; \
size_t y; \
} name; \
name alloc_##name(size_t x,size_t y)
#define DEFINE_MATRIX_OPS(type,name) \
struct matrix_##type##_t \
alloc_##name(size_t x, size_t y) { \
size_t i; \
struct matrix_##type##_t ret; \
type **m; \
\
m = (type **)malloc(x*sizeof(type *)); \
for(size_t i=0;i<x;i++) \
m[i] =(type *) malloc(y*sizeof(type)); \
ret.x=x; \
ret.y=y; \
ret.matrix=m; \
return ret; \
}
You'd then use these like this:
// At the top level of the file
DECL_MATRIX(double, dmat);
DECL_MATRIX(int, imat);
DEFINE_MATRIX_OPS(double, dmat);
DEFINE_MATRIX_OPS(int, imat);
// In a function
dmat d = alloc_dmat(3,3);
imat i = alloc_imat(2,6);
As a design note, it's better for matrixes of a fixed size to allocate the memory for the elements as a single block and to use a little math to index into them. Thus instead of ary[a][b]
you use ary[a*x_size+y]
. You can wrap this all up in more macros if you want, but it is much more efficient, both in terms of memory management and access.