0

I feel like I've attempted every combination I know of to get this to work and can't figure it out. How can I scanf() into an int** passed as a pointer to a function? I tried searching but couldn't find this, if it's a duplicate please let me know and I'll delete. It begins to run and after entering a few values it segfaults.

Here's my code, I think it's messing up on the scanf() line of the setMatrix() function:

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

// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {  
        int **mat = calloc(rmax, sizeof(int*));
        for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
        return mat;
}

// fill matrix
void setMatrix(int ***mat, int r, int c){
    printf("Insert the elements of your matrix:\n");
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            printf("Insert element [%d][%d]: ", i, j);
            scanf("%d", mat[i][j]); // problem here??
            printf("matrix[%d][%d]: %d\n", i, j, (*mat)[i][j]);
        }
    }   
    return;
}

// print matrix
void printMatrix(int ***mat, int r, int c){ 

    for (int i=0; i<r;i++){
        for (int j=0; j<c;j++) {
                printf("%d ", (*mat)[i][j]);
        }
        printf("\n");
    }

}

int main(int argc, char *argv[]) {

    int r = 3, c = 3;

    int **mat = callocMatrix(r, c);

    setMatrix(&mat, r, c);

    printMatrix(&mat, r, c);
}
Austin
  • 6,921
  • 12
  • 73
  • 138
  • Note that 'double pointer' in the title is misleading. You're referring to `int **` but it sounds like you're referring to `double *`. – Jonathan Leffler Jul 01 '16 at 00:00

2 Answers2

3

There is no need to use triple pointer ***. Passing two-dimensional array will work as is. Here is the code:

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

// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
    int **mat = calloc(rmax, sizeof(int*));
    for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
    return mat;
}

// fill matrix
void setMatrix(int **mat, int r, int c){
    printf("Insert the elements of your matrix:\n");
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            printf("Insert element [%d][%d]: ", i, j);
            scanf("%d", &mat[i][j]); // no problem here
            printf("matrix[%d][%d]: %d\n", i, j, mat[i][j]);
        }
    }
}

// print matrix
void printMatrix(int **mat, int r, int c){

    for (int i=0; i<r;i++){
        for (int j=0; j<c;j++) {
                printf("%d ", mat[i][j]);
        }
        printf("\n");
    }
}

int main(int argc, char *argv[]) {

    int r = 3, c = 3;

    int **mat = callocMatrix(r, c);

    setMatrix(mat, r, c);

    printMatrix(mat, r, c);
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
ilya1725
  • 4,496
  • 7
  • 43
  • 68
  • Someone told me if I wanted to edit a pointer to a pointer from another function I need to pass as a pointer to the double pointer, is this just false or did I misunderstand some way? – Austin Jun 30 '16 at 23:46
  • 1
    Also I tried `scanf("%d", &(*mat)[i][j]);` just now and that also worked, is this a bad way to do it? – Austin Jun 30 '16 at 23:49
  • 1
    That is correct if you want to edit a pointer. In this case you are not editing a pointer - you are changing the value the pointer points to. So unless `setMatrix` will change the matrix location in memory, like `callocMatrix`, there is no need to pass the matrix as a pointer. – ilya1725 Jun 30 '16 at 23:50
  • 1
    `scanf("%d", &(*mat)[i][j]);` is not a bay way. Just why complicate things? – ilya1725 Jun 30 '16 at 23:51
  • Ahhh, I didn't realize the difference between editing and changing value it points to, thank you! – Austin Jun 30 '16 at 23:53
  • I have one more question if you have time, now if I do `free()` from `main()` will it free everything I created? – Austin Jul 01 '16 at 00:23
  • 1
    Technically, if you just exit the application the OS will free it for you. But it is a good habit to cleanup after yourself. You essentially have to do the freeing in reverse order: first free the rows in the loop, then free the column array. – ilya1725 Jul 01 '16 at 00:26
2

Should be:

scanf("%d", &(*mat)[i][j]);

You're passing a pointer to you matrix object, so you need to dereference it (with *) just as you do with printf. scanf then needs the address of the element to write into, so you need the &

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226