473,386 Members | 1,819 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Arbitrary length multi-dimensional arrays

kd
Newbie question here. It's been a while since I've done C programming,
and I hit a wall last night.

Let's say I have a three dimensional array, like so:

int p[2][3][3] =
{{{0,0,0},
{1,1,1},
{0,1,0}},

{{0,1,0},
{1,1,0},
{0,1,0}}};

I also have a number of other three dimensional arrays, generated with
a code generating script. The size of each dimension varies with each
one. Some are [5][3][3], some are [2][5][5], etc...

How would I declare a variable that could hold any of these
3-dimensional arrays? I'm tripping over the pointer syntax.

I'd like to be able to do something like:
int ***val = p; //The variable p from the last example.

I'm pretty sure that ***val is the wrong way to go about it.

Thanks for your help!

-kd

Jun 26 '06 #1
8 2658
kd wrote:
Newbie question here. It's been a while since I've done C programming,
and I hit a wall last night.

Let's say I have a three dimensional array, like so:

int p[2][3][3] =
{{{0,0,0},
{1,1,1},
{0,1,0}},

{{0,1,0},
{1,1,0},
{0,1,0}}};

I also have a number of other three dimensional arrays, generated with
a code generating script. The size of each dimension varies with each
one. Some are [5][3][3], some are [2][5][5], etc...

How would I declare a variable that could hold any of these
3-dimensional arrays? I'm tripping over the pointer syntax.

I'd like to be able to do something like:
int ***val = p; //The variable p from the last example.

I'm pretty sure that ***val is the wrong way to go about it.


No you'd need three levels of indirection. A smart way though is to
just have a single pointer and compute the address yourself, especially
if you're dealing with a *variable* number of dimensions.

Tom

Jun 26 '06 #2
kd posted:
Newbie question here. It's been a while since I've done C programming,
and I hit a wall last night.

Let's say I have a three dimensional array, like so:

int p[2][3][3] =
{{{0,0,0},
{1,1,1},
{0,1,0}},

{{0,1,0},
{1,1,0},
{0,1,0}}};

I also have a number of other three dimensional arrays, generated with
a code generating script. The size of each dimension varies with each
one. Some are [5][3][3], some are [2][5][5], etc...

How would I declare a variable that could hold any of these
3-dimensional arrays? I'm tripping over the pointer syntax.

Do you want a pointer to the first element of the array?

int array1[2][3][3];
int array2[5][3][3];
int array3[2][5][5];
int *p;

p = ***array1;
p = ***array2;
p = ***array3;
Writing:

array[0]

is the same as writing:

*array
Therefore:

***array

(which can also be written as):

*(*(*array))

becomes:

((array[0])[0])[0]
which, because of C operator precedence rules, is simply:

array[0][0][0]
--

Frederick Gotham
Jun 26 '06 #3
On 2006-06-26, kd <Th*****@gmail.com> wrote:
Newbie question here. It's been a while since I've done C programming,
and I hit a wall last night.

Let's say I have a three dimensional array, like so:

int p[2][3][3] =
{{{0,0,0},
{1,1,1},
{0,1,0}},

{{0,1,0},
{1,1,0},
{0,1,0}}};

I also have a number of other three dimensional arrays, generated with
a code generating script. The size of each dimension varies with each
one. Some are [5][3][3], some are [2][5][5], etc...

How would I declare a variable that could hold any of these
3-dimensional arrays? I'm tripping over the pointer syntax.

I'd like to be able to do something like:
int ***val = p; //The variable p from the last example.

I'm pretty sure that ***val is the wrong way to go about it.


No, ***p will do it. You'll be able to go through the array with p++,
(*p)++, and (**p)++, depending on which dimension you are moving
through. Indeed, it is pretty complicated.

Why are you doing this?

--
Andrew Poelstra < http://www.wpsoftware.net/blog >
To email me, use "apoelstra" at the above address.
I know that area of town like the back of my head.
Jun 26 '06 #4
Frederick Gotham schrieb:
<snip>
Do you want a pointer to the first element of the array?

int array1[2][3][3]; <snip>
int *p;

p = ***array1;


You are assigning an int value to a pointer.
Bad idea.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Jun 26 '06 #5
Michael Mair posted:
Frederick Gotham schrieb:
<snip>
Do you want a pointer to the first element of the array?

int array1[2][3][3];

<snip>

int *p;

p = ***array1;


You are assigning an int value to a pointer.
Bad idea.

Cheers
Michael

Wups.
p = **array1;

--

Frederick Gotham
Jun 26 '06 #6
On 2006-06-26, kd <Th*****@gmail.com> wrote:
Newbie question here. It's been a while since I've done C programming,
and I hit a wall last night.

Let's say I have a three dimensional array, like so:

int p[2][3][3] =
{{{0,0,0},
{1,1,1},
{0,1,0}},

{{0,1,0},
{1,1,0},
{0,1,0}}};

I also have a number of other three dimensional arrays, generated with
a code generating script. The size of each dimension varies with each
one. Some are [5][3][3], some are [2][5][5], etc...

How would I declare a variable that could hold any of these
3-dimensional arrays?


You can't really. The thing to think about is how does the compiler
interpret an expression like:

p[i][j][k]

Suppose p is declared int p[2][3][4]. To find its way to element i,j,k,
the compiler needs to work out the offset from the start of where p is
stored to this element. This amounts to something like:

4*3*i*n + 3*j*n + k*n

where n is sizeof (int). The point is the compiler needs to know the 3
and the 4, which it determined by looking at the type of p.

You can make a pointer to p like this:

int (*pp)[2][3][4] = &p;

or even like this:

int (*pp)[][3][4] = &p;

since the compiler needs to know the 3 and the 4, but not the 2.

But you should get an "initialization from incompatible pointer type" or
similar warning if you try to make pp point to an array that was
declared int q[2][5][5]. If you force the initialization with a cast,
you will get the wrong results when you use pp because the compiler will
be working with the wrong dimensions for q.
Jun 26 '06 #7
kd schrieb:
Newbie question here. It's been a while since I've done C programming,
and I hit a wall last night.

Let's say I have a three dimensional array, like so:

int p[2][3][3] =
{{{0,0,0},
{1,1,1},
{0,1,0}},

{{0,1,0},
{1,1,0},
{0,1,0}}};

I also have a number of other three dimensional arrays, generated with
a code generating script. The size of each dimension varies with each
one. Some are [5][3][3], some are [2][5][5], etc...

How would I declare a variable that could hold any of these
3-dimensional arrays? I'm tripping over the pointer syntax.

I'd like to be able to do something like:
int ***val = p; //The variable p from the last example.

I'm pretty sure that ***val is the wrong way to go about it.


It is the wrong way.
int (*val)[3][3] = p;
is the right way to deal with arbitrary amounts of "3 by 3" matrices.
If you want to be able to deal with "arbitrary amounts of arbitrary
row by arbitrary column number matrices", you need three levels of
indirection. For every level but the last you need "index arrays".

Now, there are two ways of representing your "3D array" in memory
which _can_ make things easier:
1) Condensed. I.e. the last column of the first row of the
first matrix is immediately followed by the first column of the
second row of the first matrix and the last column of the last
row of the first matrix is immediately followed by the first
column of the first row of the second matrix.
This means that you could do with one array of int and could
access everything "matrixlike" via
#define INDEX(i, j, k, num_j, num_k) \
(((i) * (max_j) + (j)) * (max_k) + (k))
and
int *array = malloc(sizeof p);
if (NULL == array) {
/* error handling and abort */
}
memcpy(array, p, sizeof p);
for (mat = 0; mat < num_mat; ++mat)
for (row = 0; row < num_row; ++row)
for (col = 0; col < num_col; ++col) {
do_something(array[INDEX(mat,row,col, num_row,num_col)]);
}

If you really insist on
int ***val;
you need the following steps:
num_mat = sizeof p/sizeof p[0];
val = malloc(num_mat * sizeof *val);
if (NULL == val) {
/* error handling and abort */
}
num_row = sizeof p[0] / sizeof p[0][0];
*val = malloc(num_mat*num_row * sizeof **val);
if (NULL == *val) {
/* error handling and abort */
}
for (mat = 1; mat < num_mat; ++mat) {
val[mat] = val[0] + mat*num_row;
}
/* 1 */
for (mat = 0; mat < num_mat; ++mat)
for (row = 0; row < num_row; ++row)
val[mat][row] = p[mat][row];
/* 2 */
in order to use
for (mat = 0; mat < num_mat; ++mat)
for (row = 0; row < num_row; ++row)
for (col = 0; col < num_col; ++col) {
do_something(val[mat][row][col]);
}
Note that this operates on the original array p.
If you want to have val as a "copy of p", you have to replace
/* 1 */ to /* 2 */ by
num_col = sizeof p[0][0] / sizeof p[0][0][0];
**val = malloc(num_mat*num_row*num_col * sizeof ***val); /*3*/
if (NULL == **val) {
/* error handling and abort */
}
memcpy(val, p, sizeof p);
for (mat = 0; mat < num_mat; ++mat)
for (row = 0; row < num_row; ++row)
val[mat][row] = val[0][0] + (mat*num_row + row)*num_col;

2) Maximum array: Say you know that the largest possible array
dimensions are MAX_MAT, MAX_ROW, MAX_COL and
MAX_MAT*MAX_ROW*MAX_COL is not too large. Then declare your
"intermediate" matrix as
int val[MAX_MAT][MAX_ROW][MAX_COL];
and copy the values:
for (mat = 0; mat < num_mat; ++mat)
for (row = 0; row < num_row; ++row)
for (col = 0; col < num_col; ++col) {
val[mat][row][col] = p[mat][row][col];
}
Merits: 1) makes it possible to just memcpy() the array but
can mean resizing of "array" or "**val", "*val", and "val",
respectively. 2) means no resizing but potentially increased
cost for copying -- and much memory consumption.

If you allocate each row separately instead of at once (/*3*/),
you can "resize" the matrix in an easier manner but have
more allocations to take care of.

It depends on your application whether 1) or 2) or a mixed
form or something completely different is best for your...
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Jun 26 '06 #8

Andrew Poelstra wrote:
Why are you doing this?


Tetris! :) Every budding game developer's first game!

It's the sequence of rotations for different pieces!

Jun 27 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Thinkit | last post by:
Are there any packages for arbitrary precision binary floats? Something along the lines of Gnu Multi Precision. I saw quite a few rationals classes, but not this. Just looking to be able to use...
3
by: Graham Nicholls | last post by:
Hi, I'm trying to size a jpeg file. The file size is held in a short (2 byte integer) at a certain offset. Once I've found these two bytes (they're in MSB,LSB order), I need to convert them to...
7
by: Nick | last post by:
Given that n = , , ] then the following code produces what I expect for x in n: for y in n: for z in n: print
8
by: John Smith | last post by:
Hi, I'm writing a library in C++ which is supposed to be used by people using C. One function I have must return a string to users which is arbitrary length. The user must be able to use this...
5
by: Mattias Brändström | last post by:
Hello! I am trying to find a minimal class/lib that handles arbitrary precision decimal numbers. I would be happy if this class supported as little as addition, subtraction, multiplication,...
4
by: Magnus Jonneryd | last post by:
I'm trying to figure out if it's possible to implement a function in C++ that has an argument list of arbitrary length. Is this possible (I don't want to use a data structure to accomplish this)? ...
3
by: Jow Blow | last post by:
I am trying to make a word wrap type function for a multi line text box field that will be saved to a text file. The word wrap property looks good in the app but when saved to a text file the line...
0
by: Jeremy Watts | last post by:
Hi, Does VB.net have an 'arbitrary length' arithmetic feature? Meaning can it handle very large real/integer number arithmetic symbolically like some other languages can? PHP for instance...
8
by: Martin the Third | last post by:
Hi, I need some help! I'm writing an infinite-precision floating point library called ipfloat (I know infinite is a misnomer - but arbitrary was taken). A quick overview: I'm storing numbers as...
12
by: Bill Mill | last post by:
Hello all, I want to have a user able to eval code in a text box. However, if he accidentally types "while(1) { i=0; }" and hits "run", I also want him to be able to hit a stop button such that...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.