NewGirl
NewGirl

Reputation: 13

How to return a double pointer from a function and send it as input into another function?

I am new to programming and am trying to use two functions for matrix (2D array) operations, where the output of one function is the input for the next. However, I do not find a way to correctly deliver the values from one function to another. When I print the outputs of the first function in main (), they are correct, but when I input them into the 2nd function and print them, the values make no sense. I have tried it a lot of ways, but it probably fails due to my lack of understanding double pointers. I am thankful for any hint or advise!

#include <stdio.h>
#include <stdlib.h>

int** td (int r_in, int c_in, int r_p, int c_p, int input[][c_in],int params[][c_p]){
    int i, j, k;
    int**y_td;
    // memory allocation
    y_td = (int*)malloc(sizeof(int*)*r_in);
    for (i=0; i < r_in; i++){
        y_td[i] = (int*)malloc(sizeof(int)*c_p);
    }

    //
    for (i=0; i < r_in; i++){
        for (j=0; j < c_p; j++){
            y_td[i][j]=0; // Initialization
            for (k=0; k < c_in; k++){
                y_td[i][j]+= input[i][k]*params[k][j];
            }
        }
    }
    return y_td;
}


int** cnv (int r_in, int c_in, int filter, int f_size, int input[][c_in], int params[][f_size][c_in]){
    int x,i,j,k,l,m,n;
    int min_len = ((r_in < f_size)? r_in:f_size);
    int max_len = ((r_in > f_size)? r_in:f_size);
    int r_out = max_len - min_len + 1;//rows_out
    int kernel;
    int** y_cnv;

    // Print input to check if it was correctly transmitted to the function
    printf("Input CV (should be equal to TD result):\n");
    for (i=0;i<r_in;i++){
        for (j=0;j<c_in;j++){
            printf("%d ", input[i][j]);
        }
        printf("\n");
    }
    printf("\n\n");

    //memory allocation
    y_cnv = (int*)malloc(sizeof(int*)*r_out);
    for (i=0; i < r_out; i++){
            y_cnv[i] = (int*)malloc(sizeof(int)*filter);
    }
    //
    for (i=0; i < filter; i++){
        for (k=0; k < r_out; k++){
            y_cnv [k][i]=0; //initialize
        }
        for (j = 0; j < c_in; j++){
            for (n = min_len-1; n < max_len; n++){
                x = n-min_len+1;
                for (m= 0; m < r_in; m++){
                    kernel = (((n-m) < min_len && (n-m) >= 0)? params[i][n-m][j]:0);
                    y_cnv[x][i] += input[m][j]*kernel;
                }
            }
        }
    }
    return y_cnv;
}

int main() {
    // create test arrays
    int A [4][2]= {{1,1},{2,2},{3,3},{4,4}};
    int B [2][3]= {{1,2,3},{2,3,4}};
    int C [2][2][3]= {{{1,1,1},{2,2,2}},{{3,3,3},{4,4,4}}};

    int** matrix;
    int i, j;
    matrix = td(4,2,2,3,A,B);

    // print the result of first function, which is input in 2nd function
    printf("The TD result is:\n");
    for (i=0;i<4;i++){
        for (j=0;j<3;j++){
           printf("%d ",matrix[i][j]);
        }
        printf("\n");
    }
    printf("\n\n");

    matrix = cnv(4,3,2,2,matrix,C);

    return 0;
}

I expect the matrix printed in main () after the first function td () to be the same as when I read it in the second function cnv () and print it there, but it is not.

Upvotes: 0

Views: 5736

Answers (1)

msebas
msebas

Reputation: 330

take a look at this question. You were hit by the same underlying problem.

Turning

int** cnv (int r_in, int c_in, int filter, int f_size, int input[][c_in], int params[][f_size][c_in])

into

int** cnv (int r_in, int c_in, int filter, int f_size, int** input, int params[][f_size][c_in])

fixes the problem you asked for.

The reason is that you allocate an array of pointers called y_td in your first function. Each of this pointers is a number naming a memory segment where you stored some real numbers. By using int input[][c_in] you tell the computer to interpret these pointers as integer numbers and when you print them you get the addresses in memory instead of the expected values, because then input[x][y] is translated to *((int *)input+x*c_in+y).

Please allow me one more comment: You should follow the comments below the question and care for all compiler warnings: If there is a warning you should treat it as an compiler error unless you exactly know what you are doing, especially in C. Your code contains some possible problem sources like the one above.

Upvotes: 3

Related Questions