Thread: Pointers to Multidimensional Arrays

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    43

    Pointers to Multidimensional Arrays

    I am not entirely clear on how to do pointers to multidimensional arrays. It seems that if p is a pointer to the first element of the multidimensional array then you cannot properly use the "p[i][j]" notation (my compiler returns an error, something along the lines of "subscripted value is neither an array nor a pointer"). Instead, you have to do a pointer to the first element of the array viewed as a 1-dim array of 1-dim arrays, which makes the typedefs somewhat more complicated. Furthermore, if you have a function which only knows the pointer to the first real element, you cannot use this trick and you have to do some arithmetic to work out the value. I am sure there must be a better way to do this.

    Code:
    #include <stdio.h>
    
    typedef int Test[8];
    
    int *TestFn(int *t)
    {
    t[11] = 4;
    return t;
    }
    
    int main ()
    {
      Test *p;
      Test k[8];
      int *t;
    
      p = &k[0];
      t = &k[0][0];
    
      t = TestFn(t);
    
      printf("%d", p[1][3]);
    
      getchar();
      return 0;
    }
    This prints the correct answer of 4, but:

    1. The line "t[11] = 4" is rather cryptic. Obviously we know it is right because 1*8 + 3*1 = 11, but someone else might not know. Is there a way to put a double subscript to show the actual array position? As I commented earlier, "t[1][3]" doesn't seem to work.
    2. It is not entirely clear that k is a two-dim array. Obviously I would like to have a definition like:

    Code:
    int k[8][8];
    but I then could not see what type to set p as. Is there a better way around this one too?

    Adam.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Code:
    #include <stdio.h>
    
    void TestFn(int t[8][8])
    {
        t[1][3] = 4;
    }
    
    int main ()
    {
      int k[8][8];
      TestFn(k);
      printf("%d", k[1][3]);
      getchar();
      return 0;
    }
    Arrays are passed as a pointer anyway, so returning the pointer doesn't usually buy much.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    43
    Hi, thanks for your quick reply. Unfortunately that was not what I was asking. I wondered how you would access, for example the [1][3] element of an array if you only had a pointer to the [0][0] element. Your solution modified my function to take as its argument a multidimensional array rather than a pointer, however that was not what I was asking. For example, what if you didn't have the actual array to pass, for instance if it was created by malloc?

  4. #4
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Two dimensional arrays are not the same as a pointer to a pointer type, and any function getting passed a two dimensional array needs to know at least the last field, eg.
    Code:
    void foo(char a[][5])
    The compiler then knows how to calculate the correct addresses.

    Any long explanation I try to offer here would be inadequate compared to the comp.lang.c FAQ section on arrays and pointers.

    Pay particular attention to questions 6.16 (dynamic multidimensional array), 6.18, 6.19, 6.20.

  5. #5
    Registered User
    Join Date
    Oct 2005
    Posts
    43
    Quote Originally Posted by cwr
    Two dimensional arrays are not the same as a pointer to a pointer type, and any function getting passed a two dimensional array needs to know at least the last field, eg.
    Code:
    void foo(char a[][5])
    The compiler then knows how to calculate the correct addresses.

    Any long explanation I try to offer here would be inadequate compared to the comp.lang.c FAQ section on arrays and pointers.

    Pay particular attention to questions 6.16 (dynamic multidimensional array), 6.18, 6.19, 6.20.
    So hold on, let me get this straight. I can create a function

    Code:
    void f(int a[][5])
    expecting an ARRAY, then pass it a pointer?

    Code:
    int a[10][5];
    f(&a[0][0]);
    Is this correct?

  6. #6
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by kidburla
    Is this correct?
    No, the function call would simply be:

    Code:
    f(a);
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  7. #7
    Registered User
    Join Date
    Mar 2005
    Posts
    135

    ...

    Quote Originally Posted by kidburla
    Hi, thanks for your quick reply. Unfortunately that was not what I was asking. I wondered how you would access, for example the [1][3] element of an array if you only had a pointer to the [0][0] element. Your solution modified my function to take as its argument a multidimensional array rather than a pointer, however that was not what I was asking. For example, what if you didn't have the actual array to pass, for instance if it was created by malloc?
    Well, if all you want is a pointer to the [0][0] element in a two-dimensional array, you'd simply need to do this:

    char arrr[5][10];
    char *p = &arr[0][0];

    *p = 's';

    putchar(arr[0][0]); // outputs character: s

    But after rereading your question, I see you meant something quite diffrent. In that case, you would need a pointer to the whole two-dimensional array, not the element. To access the n index of the two-dimensional array (read: arr[n]) you would first create and initialize a pointer to a two-dimensional array with (we'll be using my example above) 10 elements in lenght, that's for the length in each array of the two-dimensional array. Also, the last index in the two-dimensional array (read: arr[FIRST_INDEX][LAST_INDEX]) is the key component here when you want to create a pointer to this object or pass it around to another function. The compiler, or rather C, needs to know how many elements over it needs to jump in order to get to the next index/array when you do something like arr[1].

    To further elaborate; to go from arr[0] to arr[1], I'll repeat: the compiler needs to know how many elements over it needs to jump in order to get to that particular index/array, thus, this is why need to provide "the pointer to the two-dimensional array" the lenght of an array in our two-dimensional array (which would be 10 in our example). let me demonstrate the pointer notation now:

    Code:
    int main(int argc, char **argv)
    {
    	char arr[5][10];
    	char (*ip)[10]; // ip is a pointer to an array of 10 character elements
    
    	ip = arr;
    
    	getchar();
    	return 0;
    }
    If this is hard to comprehend, let me ask you this: when you do this:

    char norm_array[5]; //normal array
    char *p = norm_array; // normal pointer, to array

    You need not do this:

    char (*p)[5] = norm_array; // <- a pointer to an array of 5 character elements.

    It reads sensible, no?. You have a pointer to an array of 5 char elements, which is what we got; an array of 5 char elements. But why do we not need to specify it as I just now did in pointer notation? Because when you do p[2] (with the _normal_pointer_), C knows how many elements to jump over to the next index/element. The keyword char in the pointer, automatically tells C that it only needs to jump n sizeof(char) over but when you have a two-dimensional array, and you create a _normal_pointer_ to it, C only knows the sizeof(char) but what about the LAST_INDEX? How does C know how many index(s)/elements(s) over it needs to jump to ge to the next index/array with only sizeof(char)? It needs a second piece of information, and that is the length of the LAST_INDEX, and it's why need to do this: char (*ip)[LAST_INDEX]; That's it, C does not need to know the FIRST_INDEX because it already knows it by the type of the object, which in this case; it's the keyword char.

    I hope this helped you understand this tough subject better. Keep on practicing and you'll eventually get it. Trust me

  8. #8
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Quote Originally Posted by kidburla
    So hold on, let me get this straight. I can create a function

    Code:
    void f(int a[][5])
    expecting an ARRAY, then pass it a pointer?

    Code:
    int a[10][5];
    f(&a[0][0]);
    Is this correct?
    When you refer to an array by itself, just the name, it becomes a non-modifiable pointer anyway.

    Indeed, a[0] is equivalent to *(a + 0), so &a[0][0] is just cancelling the * out to just leave a. As said above, it would just be f(a);

  9. #9
    Registered User
    Join Date
    Oct 2005
    Posts
    43
    Quote Originally Posted by hk_mp5kpdw
    No, the function call would simply be:

    Code:
    f(a);

    But I SAID when you only knew the pointer to the [0][0] element. I need to be passing a pointer, not the entire array. Passing the array is not what I'm interested in, I already know how to do that.

  10. #10
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by kidburla
    But I SAID when you only knew the pointer to the [0][0] element. I need to be passing a pointer, not the entire array. Passing the array is not what I'm interested in, I already know how to do that.
    Apparently not. A correct reply to the contrary has already been posted in this thread.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  11. #11
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Quote Originally Posted by kidburla
    But I SAID when you only knew the pointer to the [0][0] element. I need to be passing a pointer, not the entire array. Passing the array is not what I'm interested in, I already know how to do that.
    f(a) doesn't pass the array, it passes the address of the [0][0] element. I thought I already explained that in my last post in this thread, sorry.

    It's impossible to literally pass an entire array to a function in C, you couldn't do it even if you wanted to.
    Last edited by cwr; 10-29-2005 at 10:53 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Input on arrays and pointers
    By cjohnman in forum C Programming
    Replies: 2
    Last Post: 05-01-2008, 01:57 PM
  2. arrays of pointers to function?????
    By andyzjk in forum C++ Programming
    Replies: 11
    Last Post: 04-17-2005, 09:55 AM
  3. pointers to arrays of structures
    By terryrmcgowan in forum C Programming
    Replies: 1
    Last Post: 06-25-2003, 09:04 AM
  4. Help understanding arrays and pointers
    By James00 in forum C Programming
    Replies: 2
    Last Post: 05-27-2003, 01:41 AM
  5. Hello all and pointers to multi-dimensional arrays
    By Mario in forum C++ Programming
    Replies: 16
    Last Post: 05-17-2002, 08:05 AM