448,590 Members | 1,145 Online Need help? Post your question and get tips & solutions from a community of 448,590 IT Pros & Developers. It's quick & easy.

# Is the name of a 2-dimensional array equal to address of  element?

 P: n/a Hello, I'm having some problems understanding 2 dimensional arrays. My problem relates to the following code: #include #define M 3 #define N 3 void ZeroInitArray(int **array, int m, int n); /* prototype */ int main(void) { int array[M][N]; int i, j; for(i=0; i < M; i++) { for(j=0; j < N; j++) { array[i][j] = i * j; } } ZeroInitArray(array, M, N); return 0; } void ZeroInitArray(int **array, int m, int n) { int i, j; for(i=0; i < m; i++) { for(j=0; j < n; j++) { array[i][j] = 0; } } } ===END OF CODE=== Error message: My compiler reports that I am passing in an incorrect pointer type. I've read the FAQ on this subject, but still no enlightenment. From what I understand, an array's name is equivalent to a pointer to it's first element. for example: int x; x = &x; /* {pointer to first element) */ So what doesn't this apply to two dimensional arrays? int x; /* to me, this two dimensional array is in fact an array of arrays.. where x is an array of int  and so is x, x , .. , x. So x would be equivalent to a pointer to the first element of it's array.. &x. So x would be equivalent to &x. The larger array (that holds the subarrays) has the name x, and it would be equivalent to the address of it's first element &x. If this address is sent properly to the receiving function I used, then there should be no problem. Why is this illegal? Any insights would be helpful */ Nov 14 '05 #1
9 Replies

 P: n/a In article <11**********************@f14g2000cwb.googlegroups .com> Luke Wu wrote:I'm having some problems understanding 2 dimensional arrays. See the comp.lang.c FAQ, section 6 (sounds like you did already), and/or . [snippage] From what I understand, an array's name is equivalent to a pointer toits first element. It gets *converted to* a pointer to the first element. So what doesn't this apply to two dimensional arrays? The trick is that C does not *have* two-dimensional arrays... int x;/* to me, this two dimensional array is in fact an array of arrays..where x is an array of int  and so is x, x , .. , x. Sox would be equivalent to a pointer to the first element of it'sarray.. All good so far, but here is where you go wrong: &x. A pointer to the first element of the array "x" is &x, not &x. See , and note the "size of the circle" parts (in this case, compare the red and black circles). These are determined by the types: &x has type "pointer to array 5 of int" or "int (*)". This type is not compatible with "int **", because "int **" does not point to a 5-int-wide circle; and indeed, trying to force it to fit (via a cast, for instance) will produce code that fails at runtime, on typical implementations. -- In-Real-Life: Chris Torek, Wind River Systems Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603 email: forget about it http://web.torek.net/torek/index.html Reading email is like searching for food in the garbage, thanks to spammers. Nov 14 '05 #2

 P: n/a So then is this assumption wrong?: sample[A][b][C][D]; /* assume we declared 4 dimensional matrix */ sample[a][b][c][d] == *(*(*(*(sample+d)+c)+b)+a); yes or no? Thank you Nov 14 '05 #3

 P: n/a "Luke Wu" wrote in <11**********************@f14g2000cwb.googlegroups .com>: #define M 3#define N 3...void ZeroInitArray(int **array, int m, int n); /* prototype */...int array[M][N];...ZeroInitArray(array, M, N);...Error message: My compiler reports that I am passing in an incorrectpointer type. Yes: you are attempting to pass a pointer to array to a function expecting a pointer to pointer. I've read the FAQ on this subject, but still no enlightenment.From what I understand, an array's name is equivalent to a pointer toit's first element. No, an array's name refers to the array. In certain (most) situations, an array expression "decays" to a pointer to its first element. One situation where it doesn't is as an argument to the sizeof operator: 'sizeof array' yields the total size of the array, not the size of a pointer to its first element. for example:int x;x = &x; /* {pointer to first element) */So what doesn't this apply to two dimensional arrays?int x; It does. However, just as an array of N int decays to a pointer to int, an array of array of N int decays to a *pointer to array of N int*. There is no further decay to a pointer to pointer to int. (If there were, what on earth would it point at, remembering that the array contains ints, not pointers?) /* to me, this two dimensional array is in fact an array of arrays..where x is an array of int  and so is x, x , .. , x. Sox would be equivalent to a pointer to the first element of it'sarray.. &x. So x would be equivalent to &x. The largerarray (that holds the subarrays) has the name x, and it would beequivalent to the address of it's first element &x. If thisaddress is sent properly to the receiving function I used, then thereshould be no problem. Why is this illegal? Any insights would behelpful */ You're nearly there. The key is that the decay from array to pointer only happens to the outermost array. I'd suggest reading and digesting the FAQ entries on this again; they explain it a lot better than I can. :) -- Mat. Nov 14 '05 #4

 P: n/a Luke Wu wrote: So then is this assumption wrong?: sample[A][b][C][D]; /* assume we declared 4 dimensional matrix */ sample[a][b][c][d] == *(*(*(*(sample+d)+c)+b)+a); yes or no? No. sample[a] == *(sample + a) sample[a][b] == *( sample[a] + b ) == *( *(sample + a) + b ) .... -- Peter Nov 14 '05 #5

 P: n/a I understand now. I think my confusion started with the fact that I didn't realize that multidimensional arrays are in fact stored in continguous storage elements and that the second dimension was just a way to step over large chunks of this contiguous array. I was assuming that there was an intermediate array (with pointers that pointed to different arrays of the last dimension) - much like one would do with dynamically allocated arrays using MALLOC. My prof should have just pointed us to the FAQ associated with this newsgroup instead of the horrid textbooks out there (Learn C in 21 seconds, etc. etc.). Peter Nilsson wrote: Luke Wu wrote: So then is this assumption wrong?: sample[A][b][C][D]; /* assume we declared 4 dimensional matrix */ sample[a][b][c][d] == *(*(*(*(sample+d)+c)+b)+a); yes or no? No. sample[a] == *(sample + a) sample[a][b] == *( sample[a] + b ) == *( *(sample + a) + b ) ... -- Peter Nov 14 '05 #6

 P: n/a Luke Wu wrote: I understand now. I think my confusion started with the fact that I didn't realize that multidimensional arrays are in fact stored in continguous storage elements and that the second dimension was just a way to step over large chunks of this contiguous array. I was assuming that there was an intermediate array (with pointers that pointed to different arrays of the last dimension) - much like one would do with dynamically allocated arrays using MALLOC. My prof should have just pointed us to the FAQ associated with this newsgroup instead of the horrid textbooks out there (Learn C in 21 seconds, etc. etc.). There's an html C89 last draft at: http://dev.unicals.com/papers/c89-draft.html and an N869 at: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n869/ I recommend starting by reading "definition of terms" and "use of the library" first. In C89 draft that would be: 1.6 DEFINITIONS OF TERMS 4. LIBRARY 4.1 INTRODUCTION in N869: 3. Terms and definitions 7. Library 7.1 Introduction After that, the descriptions of the functions in the standard library are pretty easy to read, as long as you remember to read the introduction to the header first. In other words, before reading N869 7.21.2.1 The memcpy function you should first review 7.21.1 String function conventions -- pete Nov 14 '05 #7

 P: n/a On Mon, 17 Jan 2005 19:25:35 -0800, Luke Wu wrote: I understand now. I think my confusion started with the fact that I didn't realize that multidimensional arrays are in fact stored in continguous storage elements and that the second dimension was just a way to step over large chunks of this contiguous array. I was assuming that there was an intermediate array (with pointers that pointed to different arrays of the last dimension) - much like one would do with dynamically allocated arrays using MALLOC. Both layouts can be achieved with or without using malloc(), for example int (*p) = malloc(4 * sizeof *p); will (if malloc succeeds) create an object that we can access through p with the same layout as int a; e.g. p accesses an equivalent element to a. The magic is in the type, p here is a pointer to an array of 5 ints. p selects a particular sub-array of 5 ints and p selects an int from that subarray. Lawrence Nov 14 '05 #8

 P: n/a Lawrence Kirby wrote: On Mon, 17 Jan 2005 19:25:35 -0800, Luke Wu wrote: I understand now. I think my confusion started with the fact that I didn't realize that multidimensional arrays are in fact stored in continguous storage elements and that the second dimension was just a way to step over large chunks of this contiguous array. I was assuming that there was an intermediate array (with pointers that pointed to different arrays of the last dimension) - much like one would do with dynamically allocated arrays using MALLOC. Both layouts can be achieved with or without using malloc(), for example int (*p) = malloc(4 * sizeof *p); will (if malloc succeeds) create an object that we can access through p with the same layout as int a; e.g. p accesses an equivalent element to a. The magic is in the type, p here is a pointer to an array of 5 ints. p selects a particular sub-array of 5 ints and p selects an int from that subarray. Lawrence So as far as the C standard is concerned, are the following true for a multidimensional array? (i.e., int array; ) 1. array < array  1a. array + 1 == array 2. array == array  3. array > array  > array  I've seen some sample programs where a multidimensional array is passed to a function, but inside the function the array is treated as a single dimensional array to step through the elements. Is this a fair treatment under the C standard? === From everyone's help, I'm coming to the realization that there are not real multidimensional arrays in C, but only 2 types of simulated arrays (1. contiguous elements, and 2. intermediate array with poitners to subarrays - where traditional declaration using int array[A][b] uses array type 1.) Thanks everyone Nov 14 '05 #9

 P: n/a On Tue, 18 Jan 2005 09:35:26 -0800, Luke Wu wrote: Lawrence Kirby wrote: On Mon, 17 Jan 2005 19:25:35 -0800, Luke Wu wrote: > I understand now. > > I think my confusion started with the fact that I didn't realize that > multidimensional arrays are in fact stored in continguous storage > elements and that the second dimension was just a way to step over > large chunks of this contiguous array. I was assuming that there was > an intermediate array (with pointers that pointed to different arrays > of the last dimension) - much like one would do with dynamically > allocated arrays using MALLOC. Both layouts can be achieved with or without using malloc(), for example int (*p) = malloc(4 * sizeof *p); will (if malloc succeeds) create an object that we can access through p with the same layout as int a; e.g. p accesses an equivalent element to a. The magic is in the type, p here is a pointer to an array of 5 ints. p selects a particular sub-array of 5 ints and p selects an int from that subarray. Lawrence So as far as the C standard is concerned, are the following true for a multidimensional array? (i.e., int array; ) This is a subject that has been open to much debate. AS such is is best to take a conservative view. It is important to remember that C doesn't have multidimensional arrays as such, it has arrays whose elements can also be arrays. There are objects within objects. So array is an array of 3 ints, array is different array of 3 ints, although both are contained within array. 1. array < array  I'll assume for all of these that you meant to compare the addresses of the elements. array and array are different arrays and relational comparisons compare pointers to elements of the same array. So this has undefined behaviour. 1a. array + 1 == array &array+1 is a valid pointer for some purposes, but for boundary reasons is not a valid pointer to array. It is a tricky case, but portable code should not assume that it works. 2. array == array  Same issues as 1a. 3. array > array  > array  That's fine, also true with array. I've seen some sample programs where a multidimensional array is passed to a function, but inside the function the array is treated as a single dimensional array to step through the elements. Is this a fair treatment under the C standard? It depends on how the code does it. For example in int *p = &array; p should only be used to point to elements of array. If you write one of int *p = (int *)array; int *p = (int *)&array; you are on safer ground. While C doesn't require a pointer to know how big the array it is pointing into is, it is *allowed* to contain boundary information, and operations may fail if those boundaries are violated. In this case you want such boundary information to relate to the top level array rather than a subarray. Lawrence Nov 14 '05 #10

### This discussion thread is closed

Replies have been disabled for this discussion. 