How to create n-dimensional array?

Is it possible to create a multidimensional array without saying at the beginning how "big" it is, and specifying it later? I mean something like

ciccio[][][]....

I would like to create a class for multidimensional matrix.
Thank you everybody
I made a multi-dimensional array class once, but I never finished the code to keep the existing data when it was resized. Here it is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//array.hpp
//This header defines the struct "array" which allows for the creation
//of dynamic arrays with any given dimension or type.
#pragma once

//#include <algorithm>
#include <cstdarg>
#include <cstring>
#include <cstdio>

#define MIN(x,y) (x>y?y:x)

enum array_error{
	none,
	no_dimensions,
	out_of_bounds};

template<typename T>
struct array{
	private:
		unsigned num_dimensions;//number of dimensions
		unsigned data_size;//size of data (in elements)
		int* dimensions;//array of dimension sizes
		T* data;//the data
		T* change_dim(unsigned ndim,va_list args){
			int size=1;
			unsigned a;
			int* ndata;
			delete[] dimensions;
			dimensions=new int[ndim];
			for(a=0;a<ndim;++a){
				dimensions[a]=va_arg(args,int);
				size*=dimensions[a];}
			ndata=new T[size];
			data_size=size;
			return ndata;}
	public:
		array_error error;//any errors in element accessing or allocation
		//accesor methods
		inline int num_dim(){
			return num_dimensions;}
		inline const int* dim_size(int x){
			return dimensions[x];}
		//use to get data directly from data array
		inline T& operator[](int x){
			return data[x];}
		//constructor
		//array(number of dimensions,<dimension sizes>...)
		array(int ndim,...){
			num_dimensions=ndim;
			error=none;
			if(ndim==0){
				error=no_dimensions;
				dimensions=NULL;
				data=NULL;
				data_size=0;}
			else{
				dimensions=new int[ndim];
				va_list args;
				va_start(args,ndim);
				int size=1;
				for(int a=0;a<ndim;++a){
					dimensions[a]=va_arg(args,T);
					size*=dimensions[a];}
				data=new T[size];
				data_size=size;
				va_end(args);}}
		//destrctor
		~array(){
			delete[] dimensions;
			delete[] data;}
		//returns a reference to the element at the given position
		//operator()(x,y,z,...)
		T& operator()(int x,...){
			int temp,pos=x,dim=1;
			unsigned a=0;
			va_list args;
			va_start(args,x);
			for(;a<num_dimensions;++a){
				if((temp=va_arg(args,int))>dimensions[a]){
					error=out_of_bounds;
					return data[0];}
				dim*=dimensions[a];
				pos+=temp*dim;}
			va_end(args);
			return data[pos];}
		//resizes the array, even with different dimensions
		//resize(number of dimensions (-1 for current),<dimension sizes>...)
		int resize(int ndim,...){
			//fix parameters
			if(ndim==0){
				error=no_dimensions;
				return 1;}
			if(ndim==-1){
				ndim=num_dimensions;}
			//variables
			int a,w=dimensions[0];
			unsigned size=1;
			T* ndata;
			va_list args;
			va_start(args,ndim);
			//change dimensions
			delete[] dimensions;
			dimensions=new int[ndim];
			for(a=0;a<ndim;++a){
				dimensions[a]=va_arg(args,int);
				size*=dimensions[a];}
			ndata=new T[size];
			data_size=size;
			//copy old data to new buffer
			for(a=0;a<MIN((signed)num_dimensions,ndim);++a){
				memcpy(ndata+dimensions[0],data+w,MIN(w,dimensions[0]));}
			delete[] data;
			data=ndata;
			num_dimensions=ndim;
			return 0;}
		//save the array to a file
		void save(char* filename){
			FILE* file=fopen(filename,"w");
			int size=datasize;
			fwrite(&size,4,1,file);
			fwrite(&num_dimensions,4,1,file);
			fwrite(dimensions,4,num_dimensions,file);
			fwrite(data,sizeof(T),size,file);
			fclose(file);}
		//load an array from the file (deletes all old data)
		void load(char* filename){
			FILE* file=fopen(filename,"r");
			int size;
			fread(&size,4,1,file);
			fread(&num_dimensions,4,1,file);
			delete[] dimensions;
			dimensions=new int[num_dimensions];
			fread(dimensions,4,num_dimensions,file);
			delete[] data;
			data=new T[size];
			fread(data,sizeof(T),size,file);
			fclose(file);}
		//returns the size in bytes of the contained data
		inline int datasize(){
			return data_size*sizeof(T);}
		//returns the number of elements contained
		inline int size(){
			return data_size;}};

I'm actually in a hurry right now, so I'll try explaining it later.
Thank goodness for mobile technology! =P

Ok, the flaws that I know about with the array class are that it doesn't have const-correctness and I never finished my resize function... If you ever do, I'd love to hear about it!

On to how it works. The array keeps the sizes of the dimensions in an int array and the actual values in a 1d array. The values are accessed using cstdarg for variable length function parameters in an overload of the () operator, which uses an extension of the formula y*width+x (which compresses a 2d array into a 1d array) to access the indices of the array.

Did you understand that? I was kind of rambling....
Last edited on
I fixed it up a bit, and even figured out how to keep the old data when resizing, but I couldn't implement it because I still don't know HOW. I'll start a new thread for that.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//array.hpp
//This header defines the struct "array" which allows for the creation
//of dynamic arrays with any given dimension or type.
#pragma once
#ifndef MULTIDIM_ARRAY
#define MULTIDIM_ARRAY

#include <cstdarg>

template<typename T>
struct array{
	private:
		unsigned num_dimensions;//number of dimensions
		unsigned data_size;//size of data (in elements)
		unsigned* dimensions;//array of dimension sizes
		T* data;//the data
		//static function to be used if memcpy is not defined
		static void* memcpy(void* dst,const void* src,unsigned len) const{
			unsigned x=0;
			while(x<len){
				src[x]=dst[x];
				++x;}
			return dst;}
	public:
		//static error variables
		static T aoob;
		static const T caoob;
		//accesor methods
		inline unsigned numdim() const{
			return num_dimensions;}
		inline unsigned dimsize(unsigned x) const{
			return dimensions[x];}
		//use to get data directly from data array
		inline T& operator[](unsigned x){
			return data[x];}
		inline const T& operator[](unsigned x) const{
			return data[x];}
		//constructor
		//no arguments
		array(){
			num_dimensions=0;
			data_size=0;
			dimensions=NULL;
			data=NULL;}
		//array(number of dimensions,<dimension sizes>...)
		array(unsigned ndim,...){
			num_dimensions=ndim;
			if(ndim==0){
				dimensions=NULL;
				data=NULL;
				data_size=0;}
			else{
				dimensions=new unsigned[ndim];
				va_list args;
				va_start(args,ndim);
				unsigned size=1;
				for(int a=0;a<ndim;++a){
					dimensions[a]=va_arg(args,T);
					size*=dimensions[a];}
				data=new T[size];
				data_size=size;
				va_end(args);}}
		//destrctor
		~array(){
			delete[] dimensions;
			delete[] data;}
		//returns a reference to the element at the given position
		//operator()(x,y,z,...)
		T& operator()(unsigned x,...){
			unsigned index,pos=x,dim=1,a=0;
			va_list args;
			va_start(args,x);
			for(;a<num_dimensions;++a){
				if((index=va_arg(args,unsigned))>dimensions[a]){
					return aoob;}
				dim*=dimensions[a];
				pos+=temp*dim;}
			va_end(args);
			return data[pos];}
		const T& operator()(unsigned x,...) const{
			unsigned index,pos=x,dim=1,a=0;
			va_list args;
			va_start(args,x);
			for(;a<num_dimensions;++a){
				if((index=va_arg(args,unsigned))>dimensions[a]){
					return aoob;}
				dim*=dimensions[a];
				pos+=temp*dim;}
			va_end(args);
			return data[pos];}
		//resizes the array, even with different dimensions
		//resize(number of dimensions (0 for current),<dimension sizes>...)
		//TODO: fix this function so that it keeps old data
		unsigned resize(unsigned ndim,...){
			//fix parameters
			if(ndim==0){
				ndim=num_dimensions;}
			//variables
			unsigned a,b,size=1,w=dimensions[0];
			T* ndata;
			va_list args;
			va_start(args,ndim);
			//change dimensions
			delete[] dimensions;
			dimensions=new unsigned[ndim];
			for(a=0;a<ndim;++a){
				dimensions[a]=va_arg(args,unsigned);
				size*=dimensions[a];}
			ndata=new T[size];
			//copy old data to new buffer
			unsigned mindim=(num_dimensions<ndim?num_dimensions:ndim);
			unsigned mindimsize;
			for(a=0;a<mindim;++a){
				mindimsize=(dimensions[a]<ndim[a]?dimensions[a]:ndim[a]);
				for(b=0;b<mindimsize;++b){
					memcpy(ndata+
			delete[] data;
			data=ndata;
			num_dimensions=ndim;
			return 0;}
		//returns the size in bytes of the contained data
		inline int datasize() const{
			return data_size*sizeof(T);}
		//returns the number of elements contained
		inline int size() const{
			return data_size;}};

#endif
Topic archived. No new replies allowed.