Thread: Array Pointers error

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    270

    Question Array Pointers error

    Hi
    Whats wrong with the following:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	int **ptr;
    	int a, b, i, j;
    
    	int array[2][4] = {{1,2,3,4}, {5,6,7,8}};
    	
    	ptr = &array[0][0];
    	for(i=0; i<=1; i++)
    	{
    		for(j=0; j<=3; j++)
    		{
    			printf("%d\n", *(*(ptr + i) + j) );
    		}
    	}
    }
    I just try run it and crashed my command prompt

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    You are calling ptr a pointer to a pointer to an int.
    Code:
    int **ptr;
    Then, you set it to be a pointer to an int and then try to use it.
    Code:
    ptr = &array[0][0];
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    What does ptr[0] point at ?
    Answer - nothing.

    Just because you can use two subscripts on both of them doesn't make them equivalent or freely interchangeable.

    > ptr = &array[0][0];
    Did you get a warning for this. You should have, and it's a big clue that something is wrong.

    Here are a couple of things which should work.
    Code:
    #include <stdio.h>
    
    int main(void)
    {
      int **ptr;
      int a, b, i, j;
    
      int array[2][4] = {{1,2,3,4}, {5,6,7,8}};
      int *parr[2] = { array[0], array[1] };
      
      ptr = parr;
      for(i=0; i<=1; i++)
      {
        for(j=0; j<=3; j++)
        {
          printf("%d\n", *(*(ptr + i) + j) );
        }
      }
    }
    
    
    #include <stdio.h>
    
    int main(void)
    {
      int (*ptr)[4];
      int a, b, i, j;
    
      int array[2][4] = {{1,2,3,4}, {5,6,7,8}};
      
      ptr = array;
      for(i=0; i<=1; i++)
      {
        for(j=0; j<=3; j++)
        {
          printf("%d\n", *(*(ptr + i) + j) );
        }
      }
    }
    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.

  4. #4
    Registered User
    Join Date
    Aug 2007
    Posts
    270
    well yea i get the error:
    multi.c:10: warning: assignment from incompatible pointer type

    I thought since its a 2D array i need a pointer to a pointer

  5. #5
    Registered User
    Join Date
    Aug 2007
    Posts
    270
    so the way i did it:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	int *ptr;
    	int a, b, i, j;
    
    	int array[2][4] = {{1,2,3,4}, {5,6,7,8}};
    	
    	ptr = &array[0];
    	for(i=0; i<=1; i++)
    	{
    		for(j=0; j<=3; j++)
    		{
    			printf("&#37;d\n", *(*(ptr + i) + j) );
    		}
    	}
    }
    there is no slight change i can do to it? As what i did seems to make sense at ptr points to array, so it should just access each element onwards
    Last edited by taurus; 10-25-2008 at 07:54 AM.

  6. #6
    Registered User
    Join Date
    Aug 2007
    Posts
    270
    Hmmm i did this: int (*ptr)[4]; and it works fine.
    Could you explain what i just did there a bit? Why is it 4 in the brackets?

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Could you explain what i just did there a bit? Why is it 4 in the brackets?
    The [4] is the minor dimension of the array you want to point to.

    So int arr[2][4][6][8] would have a pointer int (*p)[4][6][8]

    Which is also what you would use if you wanted to pass the array to a function, as in
    void foo ( int (*p)[4][6][8] );

    Which would be called with
    foo( arr );
    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.

  8. #8
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    And in case you are wondering, this is not valid:
    Code:
    int*** ptr;
    int a[10][10][10];
    ptr = a;
    Remember that you can "convert an array to a pointer" only for one dimension. This is valid:
    Code:
    int* ptr;
    int a[10]
    ptr = a;
    So in order to point to a 3d dimensional array you would do what you did:
    Code:
    int (*p)[10][10];
    int a[10][10][10];
    p = a;
    Now why the first code wouldn't work is a long story

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by taurus View Post
    so the way i did it:
    [...]
    there is no slight change i can do to it? As what i did seems to make sense at ptr points to array, so it should just access each element onwards
    Why do you want to use a (seperate) pointer to do this? Your code will be simpler without the unecessary complication:

    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	int a, b, i, j;
    
    	int array[2][4] = {{1,2,3,4}, {5,6,7,8}};
    	
    	for(i=0; i<=1; i++)
    	{
    		for(j=0; j<=3; j++)
    		{
    			printf("%d\n", array[i][j]);
    		}
    	}
    }
    Also, understand that as with a char array, the name of an int array is implicitly a pointer to it. But you can't really use **array to cycle throught the arrays because it's actually a pointer to an array of pointers:

    printf("%d\n", **array);

    will print the number at array[0][0], but

    printf("%d\n", **(array+1));

    will print the number at array[1][0] (5). You might want to use different numbers for your experiments because **array+1 will give you 2 -- but this is not array[0][1], it's array[0][0] (1) + 1.

    *(array[i]+j) will work as well.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by taurus View Post
    Hmmm i did this: int (*ptr)[4]; and it works fine.
    Could you explain what i just did there a bit? Why is it 4 in the brackets?
    I would guess because it's array[2][4]. This is a version of *(array[i]+j).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Registered User
    Join Date
    Aug 2007
    Posts
    270
    C_ntua you said this:
    int (*p)[10][10];
    int a[10][10][10];
    p = a;

    Would it make sense then i could do this:
    int (*p)[10][10];
    int a[10]:
    p = a;

    and it would be the same thing?

  12. #12
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    The second is wrong. You have to think the types:
    Code:
    int* p;   // int*
    int** p; //int**
    int a[];   //int[]
    int a[][]; //int [][]
    You can convert one dimension. Thus, a [] to a *. So this is valid:
    Code:
    int* = int[]
    int** = int (*)[]
    int**** = int (*)[][][]
    But not more than one. This in invalid:
    Code:
    int** = int[][]
    And this are different:
    Code:
    int *p[10];    // an array of int*. Thus 10 pointers to int
    int (*p)[10]; // one int[]. Thus one pointer to a 1D array with 10 elements
    hope this helps

  13. #13
    Registered User
    Join Date
    Aug 2007
    Posts
    270
    Yea thanks, makes sense a lot more now

    One question
    say i hae a function to receive a pointer to 2d array
    I would first pass the array to the fucntion like this:
    function(array);

    then the fuction would be:
    void function (int **array)

    How do i access the elements that have been passed?
    is it just like?:
    *(*(array + i) + j)
    Last edited by taurus; 10-25-2008 at 09:39 AM.

  14. #14
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    This is a detail that isn't clarified well.
    No, you the function would be this void function(int array[10][10]). And you would pass the array as function(array).

    Think for a second the difference. You declare a function that takes an array 10x10. Not ANY size array. Now, think that you can ommit ONE dimension size. Thus declare a funciton void function(int array[][10]). But not BOTH. This is invalid: void function(int array[][]).

    If you want more in-depth:
    Why is it invalid? ThBecause the compiler needs to know one dimension. So you have to clarify these two meaning in your head:
    1) array
    2) pointers with indexes

    An array is declared an array. So a 2d array is a int array[10][10]. An index is used for arrays AND pointers. So if you declare:
    int** ptr
    then you can use the indexes. So you can do ptr[1][1] for example. And yes that would mean *(*(ptr+1)+1).
    If you want to convert a pointer to an array, you have to follow the one dimension thing.

    Now, if you declare int array[10][10] and you get a[1][1] this is NOT the same as *(*(a+1)+1). How it is translated depends from the system. Think though why they are not the same.
    If you do *(*(a+1)+1), then you need to do a+1, dereference, add 1, derreference.
    Couldn't you do instead *(a+10*1+1)? Thus dereference once? If you don't understand how this would work I will explain more.
    If you do, then the second method is valid because you KNOW one dimension. That one dimension of a is sized 10. With pointers you don't know dimensions. So this is not valid.
    So the array will use the faster method available.
    With a pointer to pointer to in you have this in the memory:
    p --> p1 p2 p3 p4 ...
    p1 --> int11 int21 int31 ....
    p2 --> int12 int22 int32 ...
    ....
    So you find what you want indirectly. But an array might not be the same. A 2D array could be like this in the memory. Lets say a 10x10 array:
    a --> int1 .... in100.
    The first 10 int are on the first row, the second 10 on the second etc etc. If the compiler knows one dimension and you ask for a[2][5] then this is the element *(a+10*2+5)

    What is the difference? With an array you have a contiguous space of memory and the elements are accessed faster. With a pointer they are accessed indirectly. Why can not include the size of one dimension? Because it is not needed. If I tell you that I am passing a int a[][10] in a function, then you can calculate the indexes as previously. The difference would be that you wouldn't know the total elements of the array, which are not checked anyways.

    Of course this is just an example. How it is implemented I don't know. In any case just remember int** p is not the same as int p[][X]

    EDIT: I apologize for the MANY above syntax, grammar, etc mistakes. I am bored to fix them though...
    Last edited by C_ntua; 10-25-2008 at 10:30 AM.

  15. #15
    Registered User
    Join Date
    Aug 2007
    Posts
    270
    hmmm
    but say i am giving a function declaration:
    void function(int **array)
    and I have to complete it to print out the contents of the array.
    I still dont quite get how i can print out the elements?
    The following is a little what I am trying:
    Code:
    #include <stdio.h>
    void function(int **array, int num)
    	{
    		int i, j;
    		int **ptr;
    		ptr = array[0][0];
    		for(i=0; i<=1; i++)
    		{
    			for(j=0; j<=3; j++)
    			{
    				printf("&#37;d\n", *(*(ptr + i) + j) );
    			}
    		}
    	}
    
    int main(void)
    {
    	int i, j;
    
    	int array[2][4] = {{1,2,3,4}, {5,6,7,8}};
    	function(array, 4);	
    }
    PS: u said int** ptr. Is that the same as int **ptr?

    thanks
    Last edited by taurus; 10-25-2008 at 12:15 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to monitor process creation?
    By markiz in forum Windows Programming
    Replies: 31
    Last Post: 03-17-2008, 02:39 PM
  2. using c++ in c code
    By hannibar in forum C Programming
    Replies: 17
    Last Post: 10-28-2005, 09:09 PM
  3. C++ compilation issues
    By Rupan in forum C++ Programming
    Replies: 1
    Last Post: 08-22-2005, 05:45 AM
  4. Learning OpenGL
    By HQSneaker in forum C++ Programming
    Replies: 7
    Last Post: 08-06-2004, 08:57 AM
  5. UNICODE and GET_STATE
    By Registered in forum C++ Programming
    Replies: 1
    Last Post: 07-15-2002, 03:23 PM