How to create a 3 dimension array dynamicly

B

Bill Sun

Hi, All

I have a conventional question, How to create a 3 dimension array by C
language.
I see some declare like this:

int *** array;
int value;

array = create3Darray(m,n,l);
value = array[j][k];

I don't know how to implement create3Darray(...) function by new function.
who can guide me? This may be a stupid problem.

Thank advanced,

Bill.
 
T

Tim Roberts

Bill Sun said:
I have a conventional question, How to create a 3 dimension array by C
language.
I see some declare like this:

int *** array;
int value;

array = create3Darray(m,n,l);
value = array[j][k];

I don't know how to implement create3Darray(...) function by new function.
who can guide me? This may be a stupid problem.


It's not a stupid question. The problem is that it can't be done, at least
not in the way you have described.

C can only do multi-dimensional array references (such as array[j][k])
when it knows at COMPILE time the size of all but the final dimension.
Otherwise, it cannot possibly figure out how to find the exact element you
want In the case where all of the dimensions are variable, you cannot use
the array[j][k] notation.

(Actually, it CAN be done if you make array a list of pointers, each of
which points to another list of pointers, each of which points to a list of
integers, but that's usually more overhead than you want.)

To do dynamic 3D arrays, you need to carry around the size of at least the
first two dimensions. For example, using this terrible code which no one
should ever use in production:


struct array3D {
int dim1;
int dim2;
int dim3;
int ptrs[];
};

#define Get3DElement(array,i,j,k) \
array->ptrs[((i*array->dim1)+j)*array->dim2+k]

array3D* create3Darray( int m, int n, int l )
{
array3D* tmp = malloc( sizeof(array3D) + m * n * l * sizeof(int) );
tmp->dim1 = m;
tmp->dim2 = n;
tmp->dim3 = l;
return tmp;
}

Now you could do:

array3D* array;
int value;

array = create3Darray(m,n,l);
value = Get3DElement(array,i,j,k);

In C++, you could write the same thing much more gracefully with classes.
 
G

Guest

I'll show you how to do it using an array of pointers. Each element of the array is a pointer to another array. This allows you to do the [] indexing for all the elements. Since there are multiple new statements, you will probally want a seperate function to delete the memory. This will need to know the values for m and n so it knows what to free

Doing so much memory maintance can be annoying and error prone, so it may be a good idea to use STL to handle as much as possible in a memory safe way

Another idea is to use a class to handle everything for you. This class can remember to dimensions so that it can be deleted correctly

Also, of note, the following method has a memory overhead of (m * n + m + 1) * sizeof(void*). An alternative is to create a 1D array with m * n * l elements and index it as i * n * l + j * l + k. Then, you can delete it with a simple call to delete []

int** create2Darray(int n, int l)
int** array
int j

array = new int**[n]
for (j = 0; j < n; j++)
array[j] = new int[l]

return array


int*** create3Darray(int m, int n, int l)
int*** array
int i

array = new int**[m]
for (i = 0; i < m; i++)
array = create2Darray(n, l)

return array


void delete3Darray(int*** array, int m, int n)
int i, j
for(i = 0; i < m; i++)
for(j = 0; j < n; j++)
delete [] array[j]

delete [] array

delete [] array


void use3Darray()
int *** array
int m = 10
int n = 20
int l = 5

array = create3Darray(m, n, l)

array[2][3][4] = 5
array[1][3][5] = 7
array[0][0][0] = array[2][3][4] + array[1][3][5]; /* array[0][0][0] = 12 *

delete3Darray(m, n)
}
 
B

Bill Sun

Hi, Tim
Thank for your answer, I really met the using int*** array to access
3D array dynamic.

The form like this:
Byte* pData = Create1DArray(m*n*k*sizeof(int));
int*** p3DData = Create3DArray(pData, m, n, k);
......
unsigned int i,j,k;
int value = p3DData[j][k];
......
the next we can using like this:
int *pBuffer = p3DData;
int *pBuffer = p3DData[j];

when I process a 3D array, you may using the pointer manner, or using the
form array[j][k] to get a value of element. I like the second option.

Is this right?
Thank you anyway.

Bill

----- Original Message -----
From: "Tim Roberts" <[email protected]>
Newsgroups:
microsoft.public.dotnet.languages.vc,microsoft.public.vc.language
Sent: Tuesday, May 18, 2004 1:38 PM
Subject: Re: How to create a 3 dimension array dynamicly

Bill Sun said:
I have a conventional question, How to create a 3 dimension array by C
language.
I see some declare like this:

int *** array;
int value;

array = create3Darray(m,n,l);
value = array[j][k];

I don't know how to implement create3Darray(...) function by new function.
who can guide me? This may be a stupid problem.


It's not a stupid question. The problem is that it can't be done, at least
not in the way you have described.

C can only do multi-dimensional array references (such as array[j][k])
when it knows at COMPILE time the size of all but the final dimension.
Otherwise, it cannot possibly figure out how to find the exact element you
want In the case where all of the dimensions are variable, you cannot use
the array[j][k] notation.

(Actually, it CAN be done if you make array a list of pointers, each of
which points to another list of pointers, each of which points to a list of
integers, but that's usually more overhead than you want.)

To do dynamic 3D arrays, you need to carry around the size of at least the
first two dimensions. For example, using this terrible code which no one
should ever use in production:


struct array3D {
int dim1;
int dim2;
int dim3;
int ptrs[];
};

#define Get3DElement(array,i,j,k) \
array->ptrs[((i*array->dim1)+j)*array->dim2+k]

array3D* create3Darray( int m, int n, int l )
{
array3D* tmp = malloc( sizeof(array3D) + m * n * l * sizeof(int) );
tmp->dim1 = m;
tmp->dim2 = n;
tmp->dim3 = l;
return tmp;
}

Now you could do:

array3D* array;
int value;

array = create3Darray(m,n,l);
value = Get3DElement(array,i,j,k);

In C++, you could write the same thing much more gracefully with classes.
 
T

Tim Roberts

Bill Sun said:
Hi, Tim
Thank for your answer, I really met the using int*** array to access
3D array dynamic.

Only if the array is a list of pointers, each of which points to a list of
pointers. You cannot dynamically allocate a straight block of ints and
then access it with p[j][k] notation. The compiler just doesn't have
enough information to find the element.
The form like this:
Byte* pData = Create1DArray(m*n*k*sizeof(int));
int*** p3DData = Create3DArray(pData, m, n, k);
.....
unsigned int i,j,k;
int value = p3DData[j][k];
.....
the next we can using like this:
int *pBuffer = p3DData;
int *pBuffer = p3DData[j];


You CAN do this by using the pointer-to-pointer-to-int method, although
p3DData would be an int **, not an int *.
when I process a 3D array, you may using the pointer manner, or using the
form array[j][k] to get a value of element. I like the second option.


I'm sure you do. It just isn't possible.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top