Mercurial > hg > x
comparison arrayalloc.h @ 1:6422640a802f
first upload
author | Wen X <xue.wen@elec.qmul.ac.uk> |
---|---|
date | Tue, 05 Oct 2010 10:45:57 +0100 |
parents | |
children | 5f3c32dc6e17 |
comparison
equal
deleted
inserted
replaced
0:9b9f21935f24 | 1:6422640a802f |
---|---|
1 #ifndef ARRAYALLOC | |
2 #define ARRAYALLOC | |
3 | |
4 /* | |
5 arrayalloc.h - 2D, 3D and 4D array memory allocation routines. | |
6 | |
7 An x-dimensional array (x=2, 3, 4, ...) is managed as a single memory block hosting all records, plus | |
8 an index block which is a (x-1)D array itself. Therefore a 2D array is allocated as two 1D arrays, a | |
9 3D array is allocated as three 1D arrays, etc. | |
10 | |
11 Examples: | |
12 Alloc2(4, N, x) declares an array x[4][N] of double-precision floating points. | |
13 Allocate3(int, K, L, M, x) allocates an array x[K][L][M] of integers and returns x as int***. | |
14 | |
15 This file also includes a garbage collector class MList that works with arrays allcoated in this way. | |
16 */ | |
17 | |
18 | |
19 #include <stdlib.h> | |
20 | |
21 //2D array allocation macros for declaring an array of double | |
22 #define Alloc2(M, N, x) \ | |
23 double **x=new double*[M]; x[0]=new double[(M)*(N)]; for (int _z=1; _z<M; _z++) x[_z]=&x[0][_z*(N)]; | |
24 #define Alloc2L(M, N, x, LIST) Alloc2(M, N, x); if (LIST) LIST->Add(x, 2); | |
25 //2D array allocation macros for all data types | |
26 #define Allocate2(INT, M, N, x) \ | |
27 x=new INT*[M]; x[0]=new INT[(M)*(N)]; for (int _z=1; _z<M; _z++) x[_z]=&x[0][_z*(N)]; | |
28 #define Allocate2L(INT, M, N, x, LIST) Allocate2(INT, M, N, x); if (LIST) LIST->Add(x, 2); | |
29 //2D array deallocation macro | |
30 #define DeAlloc2(x) {if (x) {delete[] (char*)(x[0]); delete[] x; x=0;}} | |
31 | |
32 //3D array allocation macro for declaring an array of double | |
33 #define Alloc3(L, M, N, x) \ | |
34 double*** x=new double**[L]; x[0]=new double*[(L)*(M)]; x[0][0]=new double[(L)*(M)*(N)]; \ | |
35 for (int _z=0; _z<L; _z++) {x[_z]=&x[0][_z*(M)]; x[_z][0]=&x[0][0][_z*(M)*(N)]; \ | |
36 for (int __z=1; __z<M; __z++) x[_z][__z]=&x[_z][0][__z*(N)]; } | |
37 //3D array allocation macros for all data types | |
38 #define Allocate3(INT, L, M, N, x) \ | |
39 x=new INT**[L]; x[0]=new INT*[(L)*(M)]; x[0][0]=new INT[(L)*(M)*(N)]; \ | |
40 for (int _z=0; _z<L; _z++) {x[_z]=&x[0][_z*(M)]; x[_z][0]=&x[0][0][_z*(M)*(N)]; \ | |
41 for (int __z=1; __z<M; __z++) x[_z][__z]=&x[_z][0][__z*(N)]; } | |
42 #define Allocate3L(INT, M, N, O, x, LIST) Allocate3(INT, M, N, O, x); if (LIST) LIST->Add(x, 3); | |
43 //3D array deallocation macro | |
44 #define DeAlloc3(x) {if (x) {delete[] (char*)(x[0][0]); delete[] x[0]; delete[] x; x=0;}} | |
45 | |
46 //4D array allocation macro for declaring an array of double | |
47 #define Alloc4(L, M, N, O, x) \ | |
48 double**** x=new double***[L]; x[0]=new double**[(L)*(M)]; \ | |
49 x[0][0]=new double*[(L)*(M)*(N)]; x[0][0][0]=new double[(L)*(M)*(N)*(O)]; \ | |
50 for (int _z=0; _z<L; _z++){ \ | |
51 x[_z]=&x[0][_z*(M)]; x[_z][0]=&x[0][0][_z*(M)*(N)]; x[_z][0][0]=&x[0][0][0][_z*(M)*(N)*(O)]; \ | |
52 for (int __z=0; __z<M; __z++){ \ | |
53 x[_z][__z]=&x[_z][0][__z*(N)]; x[_z][__z][0]=&x[_z][0][0][__z*(N)*(O)]; \ | |
54 for (int ___z=1; ___z<N; ___z++) x[_z][__z][___z]=&d[_z][__z][0][___z*(O)]; }} | |
55 //4D array deallocation macro | |
56 #define DeAlloc4(x) {if (x) {delete[] (char*)(x[0][0][0]); delete[] x[0][0]; delete[] x[0]; delete[] x; x=0;}} | |
57 | |
58 | |
59 /* | |
60 MList is a garbage collector for arrays created using Alloc* or Allocate* (*=2, 3, 4). After being | |
61 added to the list the arrays will be automatically freed when MList is deleted. | |
62 | |
63 Using MList: | |
64 Create an MList object and add all buffers (1D, 2D, 3D or 4D) to be recycled to the MList using | |
65 MList::Add(...). Deleting the MList will recycle all the added buffers. | |
66 | |
67 Example: | |
68 Alloc2L(4, N, x, mlist) declares 2D array x and registers it with garbage collector mlist,so that x is | |
69 freed when mlist is deleted. | |
70 */ | |
71 class MList | |
72 { | |
73 public: | |
74 int cap[4]; | |
75 int count[4]; | |
76 void** List[4]; | |
77 MList(){for (int i=0; i<4; i++) cap[i]=64, count[i]=0, List[i]=(void**)malloc(sizeof(void*)*cap[i]);} | |
78 ~MList(){ | |
79 for (int i=0; i<count[0]; i++){delete[] (char*)(List[0][i]); List[0][i]=0;} free(List[0]); | |
80 for (int i=0; i<count[1]; i++){void** tmp=(void**)List[1][i]; DeAlloc2(tmp); List[1][i]=0;} free(List[1]); | |
81 for (int i=0; i<count[2]; i++){void*** tmp=(void***)List[2][i]; DeAlloc3(tmp); List[2][i]=0;} free(List[2]); | |
82 for (int i=0; i<count[3]; i++){void**** tmp=(void****)List[3][i]; DeAlloc4(tmp); List[3][i]=0;} free(List[3]);} | |
83 void __fastcall Add(void* item, int Dim){ | |
84 int Gr=Dim-1; if (count[Gr]==cap[Gr]) IncCap(Gr); List[Gr][count[Gr]++]=item;} | |
85 void IncCap(int Gr){cap[Gr]+=64; List[Gr]=(void**)realloc(List[Gr], sizeof(void*)*cap[Gr]);} | |
86 }; | |
87 | |
88 #endif |