Thread: Passing 2D array to function via pointer of pointer

  1. #1
    Registered User
    Join Date
    Mar 2016
    Posts
    203

    Passing 2D array to function via pointer of pointer

    I have been using a pointer of pointer to dynamically allocate memory for a 2D array but my question is whether I then pass a 2D array to function using a pointer of pointer representation of this array?

    Shown below (a) my code for dynamic memory allocation for 2D array using pointer of pointer and (b) some code for passing 2d array to functions using pointers and what, I think, a function using pointer of pointer for a 2D array might look like but I can't seem to figure out how to actually pass the 2D array into this function using a pointer of pointer and so the first parameter/argument of this function is left out. Any help would be most appreciated. Thanks

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    int main(){
    	int** x;							// using pointer of pointer to represent 2D array; 
    	int num_rows, num_cols; 			// other variable declarations; 
    	int i, j; 
    	
    	printf("Enter number of rows: ");
    	scanf("%d", &num_rows); 			// setting number of rows in matrix; 
    	printf("Enter number of columns: ");
    	scanf("%d", &num_cols);				// setting number of cols in matrix; 
    	
    	x = (int**)malloc(num_rows * sizeof(int*)); // allocates memory for each row starting from the first element; 
    	for (i = 0; i < num_rows; i++) {
      x[i] = (int*)malloc(num_cols * sizeof(int)); // for each row starting from its first element, allocates memory 
      										// according to the size of cols; 
    }
    printf("Enter the matrix elements row by column: \n");
    	for(i = 0; i < num_rows; i++){
    		for (j = 0; j < num_cols; j++){
    			scanf("%d", x[i]+j);			// user input of matrix numbers; 
    		}
    	}
    printf("The matrix entered was: \n");
    	for(i = 0; i < num_rows; i++){
    		for (j = 0; j < num_cols; j++){
    			printf("%d\t", *(x[i]+j));
    		}
    		printf("\n");						// console display of matrix numbers; 
    	}
    for (i = 0; i < num_rows; i++) {
      free(x[i]);
    }
    free(x);									// freeing allocated memory; 
    }
    And here's the code for passing 2D array to functions using pointers and pointer of pointer, leaving out the part that I can't figure out, as mentioned above:

    Code:
    #include<stdio.h>
    
    
    void print_matrix_ref1(int(*arr)[5], int rows); // passing by ref with explicit declaration of pointer; 
    void print_matrix_ref2(int(*arr), int rows, int cols); // passing by ref with explicit declaration of pointer and 
    													// separate row and col parameters; 	
    void print_matrix_ref3(int(**arr), int rows, int cols); // passing by ref with explicit declaration of pointer of pointer
    														// and separate row and col parameters; 
    
    
    int main(){
    	int matrix [2][5] = {{1,2,3,4,5},{5,6,7,8,9}}; // given 2D array or matrix; 
    	print_matrix_ref1(matrix, 2);					// calling the various functions; 
    	print_matrix_ref2(matrix[0], 2, 5);
    	print_matrix_ref3(matrix???, 2, 5);			// not sure how to pass the matrix as a pointer of pointer; 
    }
    void print_matrix_ref1(int(*arr)[5], int rows){		// passing by ref with explicit declaration of pointer;
    	int i, j;
    	printf("Enter number of rows: ");
    	scanf("%d",&rows);
    	for (i = 0; i < rows; i++) {
            for (j = 0; j < 5; j++)
            {
                printf("%d\t", (*arr)[j]);
            }
            arr++; // without this statement the pointer doesn't move to the next row but prints the first row 4 times! 
            printf("\n");
    	}
    }
    void print_matrix_ref2(int(*arr), int rows, int cols){ // passing by ref with explicit declaration of pointer and
    	int i, j; 											// separate row and col parameters;
    	printf("Enter number of rows: ");
    	scanf("%d",&rows);
    	printf("Enter number of cols: ");
    	scanf("%d",&cols);
    	for (i = 0; i < rows; i++) {
            for (j = 0; j < cols; j++)
            {
                printf("%d\t", *(arr+(i*cols)+j));
            }
            printf("\n");
    	}
    }
    void print_matrix_ref3(int(**arr), int rows, int cols){ // passing by ref with explicit declaration of pointer of pointer
    	int i, j; 											// and separate row and col parameters;
    	printf("Enter number of rows: ");
    	scanf("%d",&rows);
    	printf("Enter number of cols: ");
    	scanf("%d",&cols);
    	for (i = 0; i < rows; i++) {
            for (j = 0; j < cols; j++)
            {
                printf("%d\t", *(arr[i]+j));
            }
            printf("\n");
    	}
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    > print_matrix_ref3(matrix???, 2, 5); // not sure how to pass the matrix as a pointer of pointer;
    The short answer is, you can't.

    matrix is an array of array of 5 int.

    It is not an array of pointers to array of 5 ints. You can easily make such a thing, but the two are not freely interchangeable in all circumstances, even if you can do [r][c] subscripting on both of them.


    > void print_matrix_ref3(int(**arr), int rows, int cols); // passing by ref with explicit declaration of pointer of pointer
    You declared the parameter as int**. The first dereference of arr is expecting to find another pointer, but there are no internal pointers inside your 2D array.

    If you need to do this, you need to construct a second array of pointers
    Code:
    int *pa[2] = { matrix[0], matrix[1] };
    print_matrix_ref3(pa, 2, 5);


    ref1 receives a pointer to an array of 5 ints. So all of these are possible.
    Code:
        print_matrix_ref1(matrix, 2);
        print_matrix_ref1(&matrix[0], 2);  // same as previous line
        print_matrix_ref1(&matrix[1], 1);  // print from the 2nd row
    ref2 receives a pointer to an int, so all of these are possible
    Code:
        print_matrix_ref2(matrix[0], 2, 5);
        print_matrix_ref2(&matrix[0][0], 2, 5);  // same as above
        print_matrix_ref2(matrix[1], 1, 5); // print from the 2nd row
        print_matrix_ref2(&matrix[1][0], 1, 5); // same as above
    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
    Jun 2015
    Posts
    1,640
    Consider:
    Code:
    int arr[2][5];
    int **pparr; // assume this has been allocated to mimic a 2d array (note the word "mimic")
    arr[0] (a.k.a., *arr) is of type int[5] (a 20-byte object, assuming 4-byte ints)
    pparr[0] (a.k.a., *pparr) is of type int* (an 8-byte object, assuming 8-byte pointers)

    They are laid out differently in memory. arr has all 10 ints laid out contiguously. This means you can access any one of them by an offset from arr. But for pparr the 10 ints are laid out as two 5-int arrays which need not be contiguous. It's even possible for the "second" 5-int array to be at a lower address than the first one. This means that it is not (generally) possible to access a particular int as a simple offset from pparr.

    It is possible, however, to allocate the ints for pparr so that they are contiguous in memory like arr. Just allocate 10 ints and then assign the row addresses to the pparr array:
    Code:
    int **pparr = malloc(ROWS * sizeof *ppar);
    *pparr = malloc(ROWS * COLS * sizeof **pparr);
    for (int i = 1; i < ROWS; i++)
        pparr[i] = *pparr + (i * COLS);
    Another difference is that they respond differently to pointer arithmetic:
    arr[0] + 1 points to an address 20 bytes higher in memory (the next row of ints).
    pparr[0] + 1 points to an address 8 bytes higher in memory (the next row pointer).

    The above considerations should explain why you can't receive an int[2][5] as an int**.

  4. #4
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    Thanks to both for your lucid comments, very helpful.

  5. #5
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    Actually if we took &x[i] as our pointer-to-pointer we could pass it to the function, one row at a time, without declaring any additional variables:

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    
    void print_matrix_ref(int(**arr), int rows, int cols);	// passing by ref with explicit declaration of pointer to pointer
    														// and separate row and col parameters;	
    int main(){
    	int** x;							// using pointer of pointer to represent 2D array; 
    	int num_rows, num_cols; 			// array row and col size; 
    	int i, j; 							// loop counter variables; 
    	
    	printf("Enter number of rows: ");
    	scanf("%d", &num_rows); 			// setting number of rows in matrix; 
    	printf("Enter number of columns: ");
    	scanf("%d", &num_cols);				// setting number of cols in matrix; 
    	
    	x = (int**)malloc(num_rows * sizeof(int*)); // allocates memory for each row starting from the first element; 
    	for (i = 0; i < num_rows; i++) {
      x[i] = (int*)malloc(num_cols * sizeof(int)); // for each row starting from its first element, allocates memory 
      										// according to the size of cols; 
    }
    printf("Enter the matrix elements row by column: \n");
    	for(i = 0; i < num_rows; i++){
    		for (j = 0; j < num_cols; j++){
    			scanf("%d", x[i]+j);			// user input of matrix numbers; 
    		}
    	}
    for (i = 0; i < num_rows; i++){
    	print_matrix_ref(&x[i], 1, num_cols);	// each pointer to pointer is a pointer to the first element of each row  
    											// which is itself a pointer;
    											// the matrix is printed out one row at a time; 
    }
    for (i = 0; i < num_rows; i++) {
       free(x[i]);						// freeing allocated memory of x; 
      }									 
    free(x);
    }
    void print_matrix_ref(int(**arr), int rows, int cols){
    	int i, j; 
    	for (i = 0; i < rows; i++) {
            for (j = 0; j < cols; j++)
            {
                printf("%d\t", *(arr[i]+j));
            }
            printf("\n");
    	}
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 09-08-2013, 06:17 PM
  2. Passing two dimensional array to function using pointer
    By Burns111 in forum C Programming
    Replies: 3
    Last Post: 11-27-2012, 10:55 AM
  3. Replies: 11
    Last Post: 12-30-2009, 04:04 PM
  4. Passing a pointer to two-dimension array in a function
    By E_I_S in forum C++ Programming
    Replies: 11
    Last Post: 06-19-2008, 09:57 AM
  5. Passing pointer to array to a function
    By Tojam in forum C Programming
    Replies: 1
    Last Post: 10-09-2002, 09:24 PM

Tags for this Thread