this only use 1 malloc call for allocate Matrix
Are other constrains ?
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#define G(a,b) if(a)goto b
#define R return
#define P printf
#define M malloc
#define F free
#define S sizeof
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned
#define i32 int
#define d64 double
/*
Each element until sz is u32
pInd[0],pInd[1],..,pInd[pInd[0]], sizeElement, sz, [matrix data]
0 1 pInd[0] pInd[0]+1 pInd[0]+2 indirizzo
1 2 pInd[0]+1 pInd[0]+2 pInd[0]+3 nelement
pInd[0]: is the number of index as 32 bit
pInd[1]: is the first max index as 32 bit
....
pInd[pInd[0]]: is the last max index
pInd[pInd[0]+1]: is the size of element as 32 bit
sz: size of "data" area
data is matrix "data" area
*/
// access to size of matrix data as pointer to u32
#define SZ(a) ((a)+*(a)+2)
// access to size element of matrix
#define SZe(a) ((a)+*(a)+1)
// access to data as pointer to u8
#define Data(a) (unsigned char*) ((a)+*(a)+3)
/*
reserve mem space to matrix of element msize for dimension
i0xi1x...xin taken as input
where i0, i1 etc are max+1 index and n<=255
the last max+1 index is -1 that end the input
Return -1 for error
Return 0 all ok
NB
**The first function to call on pm [construct matrix] **
**the last function to call on pm [destruct matrix] **
*/
i32 Mcon(u32** pm, u32 msize, ...)
{va_list ap;
u32 v, i, s, j;
u32 arr[256];
G(pm, l1);
l0: R -1; // for error
n0: va_end(ap); *pm=0; G(1,l0);
l1: G(msize, l3); F(*pm); /* free the Matrix */
l2: R 0; // for all ok
y0: va_end(ap); G(1,l2);
l3: va_start(ap, msize); G(msize>0xFFF, n0); G(msize==1, n0); i=0;
l4: v=va_arg(ap, u32); //v the first index;if i==0 means no element
G(v>0xFFFF && v!= -1, n0); G(v!=-1, la); G(i==0, n0);
s=1; j=1;
l5: s*=arr[j-1]; G(s>0xFFFFF, n0); ++j; G( j<=i, l5);
s*=msize; G(s>0xFFFFF, n0);
*pm=M((i+3)*sizeof(u32)+s); G(*pm==0, n0);
(*pm)[0]=i; *SZe(*pm)=msize; *SZ(*pm)=s; j=1;
l6: (*pm)[j]=arr[j-1]; ++j; G( j<=i, l6);
G(1,y0);
la: G(i>255, n0); arr[i++]=v; G(1,l4);
}
// return one pointer to element
// or 0 if find some error
u8* Aelm(u32* pm, ...)
{va_list ap;
u8 *r;
u32 i,j,maxn, max, size, v, s, Index[256];
G(pm,l1);
l0: R 0;
n0: va_end(ap); G(1,l0);
l1: maxn=pm[0]; size= *SZe(pm); // 0 1
i=1; G(maxn>=256||maxn==0, l0); //for 2x2 y*n+x (y,x)e[0..m-1]x[0..n-1]
va_start(ap, pm); // gets all index i0 i1 maxn=2
l2: v=va_arg(ap, u32); // gets one index
G(v>=pm[i], n0); // if that index >= sup index error
Index[i-1]=v; // save that index
++i; G(i<=maxn, l2);
v=va_arg(ap, u32); G(v!= -1, n0); // ceck value
i=0; s=Index[maxn-1]; // s is the index where is the elment
l3: s=s+Index[i]*(pm[i+2]); ++i; G(i<maxn-1, l3);
v=s*size; r=Data(pm); r+=v;
va_end(ap);
R r;
}
// for now only nxm matrix of u8 u16 u32 d64[double]
void PrntMtrx(u32* m)
{va_list ap;
d64 dv;
u8 *p, *pmax;
u32 i,j,maxn, max, size, v;
u32 Index[256];
G(m, l1);
l0: R; // error
l1: G(m[0]>2, l0);
size= *SZe(m);
G(size>8, l0);
i=0; p=Data(m); pmax=p+(size*m[1]*m[2]);
m0: G(size==1,l2);G(size==2,l3);G(size==4,l4);G(size==8,l11);G(1,l0);
l11:dv=*(d64*)p; P("%10.2f",dv); G(1,l5);
l2: v=*(u8*) p; P("%3u ", v); G(1,l5);
l3: v=*(u16*)p; P("%5u ", v); G(1,l5);
l4: v=*(u32*)p; P("%10u ", v);
l5: G( (i+1)% m[2] != 0, l6); P("\n");
l6: p+=size; ++i; G(p<pmax, m0);
R;
}
int main(void)
{u32 *m1=0, *m2=0, *m3=0, *m4=0, *m5=0;
G(Mcon(&m1, S(u32), 2, 2, -1), z); // constructor m1 Matrix 2x2 of u32 element
G(Mcon(&m2, S(u32), 2, 3, -1), z);
G(Mcon(&m3, S(u32), 2, 1, -1), z);
G(Mcon(&m4, S(u32), 1, 2, -1), z);
G(Mcon(&m5, S(d64), 2, 2, -1), z);
// fill the matrix
*(u32*)Aelm(m1, 0,0, -1)=123; *(u32*)Aelm(m1, 0,1, -1)=124;
*(u32*)Aelm(m1, 1,0, -1)=125; *(u32*)Aelm(m1, 1,1, -1)=126;
*(u32*)Aelm(m2, 0,0, -1)=127; *(u32*)Aelm(m2, 0,1, -1)=128; *(u32*)Aelm(m2, 0,2, -1)=129;
*(u32*)Aelm(m2, 1,0, -1)=130; *(u32*)Aelm(m2, 1,1, -1)=131; *(u32*)Aelm(m2, 1,2, -1)=132;
*(u32*)Aelm(m3, 0,0, -1)=133;
*(u32*)Aelm(m3, 1,0, -1)=134;
*(u32*)Aelm(m4, 0,0, -1)=135; *(u32*)Aelm(m4, 0,1, -1)=136;
*(d64*)Aelm(m5, 0,0, -1)=123456.123; *(d64*)Aelm(m5, 0,1, -1)=12345.124;
*(d64*)Aelm(m5, 1,0, -1)=123.744; *(d64*)Aelm(m5, 1,1, -1)=1.749;
//print the matrix
P("M1:\n");PrntMtrx(m1); P("\n\n"); P("M2:\n"); PrntMtrx(m2); P("\n\n");
P("M3:\n");PrntMtrx(m3); P("\n\n"); P("M4:\n"); PrntMtrx(m4); P("\n\n");
P("M5:\n"); PrntMtrx(m5); P("\n\n");
z: Mcon(&m5, 0); // destructor
Mcon(&m4, 0);
Mcon(&m3, 0);
Mcon(&m2, 0);
Mcon(&m1, 0);
R 0;
}
-------------------------------
M1:
123 124
125 126
M2:
127 128 129
130 131 132
M3:
133
134
M4:
135 136
M5:
123456.12 12345.12
123.74 1.75