Thread: function reveives a 2-d array as parameter

  1. #1
    Registered User
    Join Date
    May 2007
    Location
    China
    Posts
    37

    function reveives a 2-d array as parameter

    hi all,
    how can i write a function which receives a 2-d array?
    my version:
    Code:
    #include <stdio.h>
    int main(void)
    {
      void fun(int *arr[10]);
    
      int twodarray[10][10] = {0};
    
      fun(twodarray);
    
    return 0;
    }
    
     void fun(int *arr[10])
     {
       int i;
       for(i=0; i<10; i++)
       {
         printf("%d", arr[0][i]);
       }
      }
    it can't be compiled, here's error mesaage
    Code:
    9 D:\Programes\OfficeWork\Dev-Cpp\Fun2darray\main.cpp cannot convert `int (*)[10]' to `int**' for argument `1' to `void fun(int**)'
    Code:
    void fun(int **arr)
    {....}
    not working neither
    BTW, how can i deal with a 3-d array?

    many thanks!

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    fun(int arr[][10]) ...
    For a 3D array, you will need to specify:
    Code:
    fun3d(int arr[][10][10]);
    Note that just becase a one-dimensional array will convert to a pointer, it doesn't automatically make a 2D array into a pointer to pointer - the compiler needs to know the dimensions aside from the first one [how LONG the 2D array is].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    May 2007
    Location
    China
    Posts
    37
    great thanks,
    i try this and it seems work fine, but i don't know why,
    can u help to explain it?
    Code:
     void fun(int (*arr)[10])

  4. #4
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Thanks Mats.

    Code:
    #include <stdio.h>
    
    void fun(int arr[][10]);
    
    int main(void) { 
    	int i, j, k = 0; 
    	
    	int twodarray[10][10] = {0};
    	
    	for (i = 0 ; i < 10 ; i++) { 
    		for (j = 0 ; j < 10 ; j++ ) { 
    			twodarray[i][j] = k ; 
    			k++ ;
    		}
    	}
    	fun(twodarray);
    
    return 0;
    }
    
    void fun(int arr[][10]) {
    	int i, j ;
    	for(i=0; i<10; i++) {
    		for ( j = 0 ; j < 10 ; j++ ) {
    			printf("&#37;d:%d = %d\n", i, j, arr[i][j]);
    		}
    	}
    }
    Todd

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, that's another variation. It basicly says "this is a pointer to an array of ten elements" [as opposed to the original form of "10 pointers to integers" - which isn't what you want].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    May 2007
    Location
    China
    Posts
    37
    thanks again,
    i've another question now,
    how to write a function that returns an address of a 2-d array?
    mine: (revised twice - thanks to matsp)
    Code:
    #include <stdio.h>
    void fun(int (*arr)[10]);
    int send(void);
    
    int main(void)
    {
        int (*ptr)[10];
        ptr = send();
        fun(ptr);
    return 0;
    }
     void fun(int (*arr)[10])
     {
       int i;
       for(i=0; i<10; i++)
       {
         printf("&#37;d", arr[0][i]);
       }
      }
      
    int send(void)        //here is the problem.....
    {
        int static twodarray[10][10] = {0};
        return twodarray;  
    }
    (thank you Todd, but pleaseforgive me using my version ...for simplicity
    Last edited by albert3721; 12-04-2007 at 07:44 AM. Reason: optimize-reedit-owe to matsp

  7. #7
    Daring to be a guru
    Join Date
    Dec 2007
    Posts
    14
    im propably using your first code.......... now i think so this would work for you........ im printing array[9][0]...........array[9][9].....

    Code:
    #include <stdio.h>
    int main(void)
    {
      int ** fun(int **arr);
      int **ptr;
      int i;
      int twodarray[10][10] = {0};
    
      ptr=fun(twodarray);
      for(i=0; i<10; i++)
       {
         printf("&#37;d\n",* ((ptr+9)+i));
       }
    
    return 0;
    }
    
     int ** fun(int **arr)
     {
       int i;
       for(i=0; i<10; i++)
       {
         printf("%d\n",* ((arr+9)+i));
       }
       return arr;
     }

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by albert3721 View Post
    thanks again,
    i've another question now,
    how to write a function that returns an address of a 2-d array?
    mine:
    Code:
    #include <stdio.h>
    void fun(int (*arr)[10]);
    int send(void);
    
    int main(void)
    {
        int (*ptr)[10];
        ptr = send;
        fun(ptr);
    return 0;
    }
     void fun(int (*arr)[10])
     {
       int i;
       for(i=0; i<10; i++)
       {
         printf("%d", arr[0][i]);
       }
      }
      
    int send(void)        //here is the problem.....
    {
        int twodarray[10][10] = {0};
        return twodarray;  
    }
    (thank you Todd, but pleaseforgive me using my version ...for simplicity
    1. You are not actually calling send, you are assigning a pointer with the address of the function send.
    2. You are returning a local variable [twodarray in send], so that variable will "disappear" when the funciton returns.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    OK, this compiles, but crashes in the first assignment in red. Something is wrong.

    Code:
    #include <stdio.h>
    #include <stdlib.h> 
    
    int ** fun1(void);
    void fun2(int **) ; 
    
    int main(void) { 
    	int i, j, k = 0; 
    	
    	int ** twodarray ;  
    			
    	twodarray = fun1();
    	for (i = 0 ; i < 10 ; i++) { 
    		for (j = 0 ; j < 10 ; j++ ) { 
    			twodarray[i][j] = k ; 
    			k++ ;
    		}
    	}
    	fun2(twodarray) ; 
    	return 0;
    }
    
    int ** fun1(void) {
    	int **arr ;  
    	arr = calloc( 10*10 , sizeof(int) ) ; 
    	return arr ; 
    	
    }
    
    void fun2(int **arr) {
    	int i, j ; 
    	for( i = 0 ; i < 10 ; i++ ) {
    		for ( j = 0 ; j < 10 ; j++ ) {
    			printf("&#37;d:%d = %d\n", i, j, arr[i][j]);
    		}
    	}
    }

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, yet again, we're attempting to convert ** into a 2D array. That's not what ** means. ** means that you have ONE variable that contains a pointer to a pointer to a integer.

    A two dimensional array is a block of memory that is x elements wide and y elements "high".

    You can use an array of y pointers that point to arrays of x elements, and a pointer to pointer that points to the y pointers. Something like this:

    Code:
    int ** fun1(void) {
    	int **arr ;  
            arr = calloc(10, sizeof(int *));   // 10 pointers to integer. 
            for(i = 0; i < 10; i++) 
            {
    	   arr[i] = calloc( 10 , sizeof(int) ) ; // 10 integers. 
            }
    	return arr ; 
    }
    Just don't forget to do the opposite to free them later on.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Got it. Thanks again!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int ** fun1(void);
    void fun2(int **) ; 
    void fun3(int **) ; 
    
    int main(void) { 
    	int i, j, k = 0; 
    	
    	int ** twodarray ;  
    			
    	twodarray = fun1();            // allocate the memory 
    	for (i = 0 ; i < 10 ; i++) {   // assign values 
    		for (j = 0 ; j < 10 ; j++ ) { 
    			twodarray[i][j] = k ; 
    			k++ ;
    		}
    	}
    	fun2(twodarray) ;   // print out the values
    	fun3(twodarray) ;   // free the memory 
    	return 0;
    }
    
    int ** fun1(void) {
    	int i,  **arr ;  
    	arr = calloc( 10 , sizeof(int) ) ; 
    		printf("Heap allocated... address=&#37;p\n", arr) ; 
    	for (i = 0 ; i < 10 ; i++) { 
    		arr[i] = calloc(10, sizeof(int) ) ; 
    		printf("Heap allocated... address=%p\n", arr[i]) ; 
    	}
    	return arr ; 
    	
    }
    
    void fun2(int **arr) {
    	int i, j ; 
    	for( i = 0 ; i < 10 ; i++ ) {
    		for ( j = 0 ; j < 10 ; j++ ) {
    			printf("%d:%d = %d\n", i, j, arr[i][j]);
    		}
    	}
    }
    
    void fun3(int ** arr) {
    	int i ;   
    	for (i = 0 ; i < 10 ; i++) { 
    		printf("Freeing Heap... address=%p\n", arr[i]) ; 
    		free(arr[i]) ; 
    	}
    	printf("Freeing Heap... address=%p\n", arr) ; 
    	free(arr) ; 
    }

  12. #12
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    I think my confusion was that the compiler was doing a lot of work for me behind the scenes when I define

    twodarray[10][10].

    I envisioned this as a block of 400 bytes (assuming an int is 4 bytes), but that is obviously not the case. The compiler is (essentially) hard coding the pointers for me, so there is really:

    40 bytes for the 10 pointers ("i")
    10 * 40 bytes for all the 2nd dimension pointers ("j")
    400 bytes for the actual integers.

    So, 840 bytes for an array of 100 integers. Is this correct?

    Todd

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You can return a pointer to a true 2D array inside a function, providing that the array is declared static (inside the function).

    However, the syntax for the function declaration is a sight to behold!
    Code:
    #include <stdio.h>
    
    int (*func(void))[10] {
        static int arr[10][10] = {
            { 1 },
            { 2 },
        };
        return arr;
    }
    
    int main ( ) {
        int r, c;
        int (*arr)[10] = func();
        for ( r = 0 ; r < 10 ; r++ ) {
            for ( c = 0 ; c < 10 ; c++ ) {
                printf( "&#37;d ", arr[r][c] );
            }
            printf( "\n" );
        }
        return 0;
    }
    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.

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Salem View Post
    However, the syntax for the function declaration is a sight to behold!
    "Beauty is in the eye of the beholder" as they say - in this case, I don't like it at all.

    Also, a static return array is only good if you either:
    - Only ever call it for ONE array at any given time - otherwise, the second array is an alias of the first one.
    - Definitely DON'T use multithreading.

    There are several ways to manage 2D arrays that is MUCH easier than returning an array from a function. For example, you can wrap the array into a struct, and use a pointer to the struct.

    Or pass a 2D array in from the lower level call, rather than return it from a higher call.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I envisioned this as a block of 400 bytes (assuming an int is 4 bytes), but that is obviously not the case. The compiler is (essentially) hard coding the pointers for me, so there is really:

    40 bytes for the 10 pointers ("i")
    10 * 40 bytes for all the 2nd dimension pointers ("j")
    400 bytes for the actual integers.
    Yes, a simple 2D array is a block of 400 bytes. There are no "hidden pointers", etc when the compiler deals with it. The pointers become a must when you try to create your own 2D array, and use it as a pointer to pointer. [This makes it flexible as to what the two dimensions are too - you just change the internals of the function to make it 20 x 20].

    You can ALSO create a block of 400 bytes, and return it using Salems "something to behold" syntax:
    Code:
    int (*func(void))[10] {
        int (*arr)[10];
        arr = calloc(10 * 10, sizeof(int));
        return arr;
    }
    This code only works for a [x][10] array - as it's a pointer to array of 10 integers.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  2. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM
  3. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  4. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  5. pointer to array as parameter to function
    By Jurgen in forum C++ Programming
    Replies: 1
    Last Post: 05-20-2004, 02:51 PM