1

My task is to write a function int *matrica1(int n). This function must create a matrix dimensions nxn and then you have to allocate its memory and in the main you have to write the elements of the matrix. I have a problem when returning pointer mat1 to **p and when i call **p i get a address instead of a number but when i call **mat1 in the function i get the number. I do not understand ?

#include <stdio.h>
int *matrica1(int n);

int main(){
    int n;
    printf("Input dimension of matrix:");
    scanf("%d", &n);

    int **p = matrica1(n);


    printf("Matrix \n\n");

    int i;
    n = n*n;
    for(i=0; i<n; i++){
        printf(" %d ", **(p+i));//I keep getting an address
    }
    return 0;
}

int *matrica1(int n){
    int mat[n][n];
    int i, j;
    int k=0;
    for(i=0; i<n; i++){
        for(j=0; j<n; j++){
            mat[i][j] = j+k;
        }
        k++;
    }

    int size = n*n;
    int **mat1 = (int*)malloc(size*sizeof(int));

    int m = 0;
    for(i=0; i<n; i++){
        for(j=0; j<n; j++){
            mat1[m] = &mat[i][j];
            m++;
        }
    }
    printf("\n\n**mat1 = %d", **mat1);//Here it returns me a number

    return mat1;
}

here how it looks like when running it

Dusan
  • 105
  • 7

1 Answers1

1

You're returning the address of a local variable.

mat1 contains pointers to element of mat. When matrica1 returns, mat goes out of scope, so pointers to its elements no longer point to valid memory. Dereferencing these pointers invokes undefined behavior.

Other problems:

  • The memory you're assigning to mat1 is not the right size. Because it is an array of int *, you should be allocating size*sizeof(int *) bytes, not size*sizeof(int) bytes.
  • matrica1 is defined to return a int * but you're returning an int ** and assigning the result to an int **. The return type of the function must match what you're returning.

Rather than having mat1 be an array of int *, make it an array of int and copy the values of mat rather than the addresses:

#include <stdio.h>
int *matrica1(int n);

int main(){
    int n;
    printf("Unesite dimenziju matrice:");
    scanf("%d", &n);

    // Have p match return type of function
    int *p = matrica1(n);


    printf("Matrix \n\n");

    int i;
    n = n*n;
    for(i=0; i<n; i++){
        // print array elements
        printf(" %d ", *(p+i));
    }
    return 0;
}

int *matrica1(int n){
    int mat[n][n];
    int i, j;
    int k=0;
    for(i=0; i<n; i++){
        for(j=0; j<n; j++){
            mat[i][j] = j+k;
        }
        k++;
    }

    int size = n*n;
    // change type of mat1 from int ** to int *, keep size the same
    int *mat1 = malloc(size*sizeof(int));

    int m = 0;
    for(i=0; i<n; i++){
        for(j=0; j<n; j++){
            // assign values of mat instead of addresses
            mat1[m] = mat[i][j];
            m++;
        }
    }
    printf("\n\n*mat1 = %d", *mat1);

    return mat1;
}

Output:

Unesite dimenziju matrice:5


*mat1 = 0Matrix 

 0  1  2  3  4  1  2  3  4  5  2  3  4  5  6  3  4  5  6  7  4  5  6  7  8
dbush
  • 205,898
  • 23
  • 218
  • 273
  • When matrica1 returns, mat goes out of scope. Can you please explain that. Dose that mean you are never allowed to return an array of addresses in c ? – Dusan Oct 11 '18 at 14:41
  • @Marko You can return an array of address (or a single address) **provided** that address is not the address of a local variable. Because `mat` no longer exists when the function `matrica1` returns, a pointer to it is not valid. The memory that was used by `mat` can be repurposed for something else. – dbush Oct 11 '18 at 14:49
  • Thank you, you have really helped me. – Dusan Oct 11 '18 at 14:55