Janska
Janska

Reputation: 41

Passing 2-d array to a function in C

I'm trying to make a function that initializes a random 2 dimensional square matrix given its variable name and number of rows and columns (n in this case). This code returns a "Segmetation fault" error and I don't know why. I've tried using & in if-else in the function initM, but then returns "error: lvalue required as left operand of assignment"Anyone knows how to make it work?

void initM (int n, int **matrix){
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++){
            if (i == j) matrix[i][j] = 101;
            else matrix[i][j] = (rand() % 101);
        }
    }
}

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

    int n = atoi(argv[1]);

    int **matrix = (int **)malloc(n*sizeof(int));
    for(int i = 0; i < n; i++) matrix[i] = (int *)malloc(n*sizeof(int));

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

    for (int i = 0; i < n; i++) free(matrix[i]);
    free(matrix);
}

Upvotes: 0

Views: 61

Answers (2)

John Bode
John Bode

Reputation: 123596

int **matrix = (int **)malloc(n*sizeof(int));

The main problem is that sizeof (int) is not the same as sizeof (int *) on your system, so you're not allocating enough space. The above call can be rewritten as

int **matrix = malloc( n * sizeof *matrix );

The cast is unnecessary1, and sizeof *matrix == sizeof (int *)2.

Similarly, you can allocate each matrix[i] as

matrix[i] = malloc( n * sizeof *matrix[i] ); // sizeof *matrix[i] == sizeof (int)

You should always check the result of a malloc, calloc, or realloc call. While failures are rare, they can happen:

int **matrix = malloc( n * sizeof *matrix );
if ( matrix )
{
  for ( i = 0; i < n; i++ )
  {
    matrix[i] = malloc( n * sizeof *matrix[i] );
    if ( matrix[i] )
      // do stuff
  }
}

Final nit - main returns int, not void. Unless your compiler specifically documents void main( int, char ** ) as a valid signature, then using it invokes undefined behavior. Your code may run just fine, but there are (admittedly old or oddball) platforms where typing main as void leads to problems.


  1. Unless you're compiling this code as C++ or working with an ancient pre-C89 compiler.
  2. sizeof is an operator, not a function - parentheses are only necessary if the operand is a type name.

Upvotes: 0

alinsoar
alinsoar

Reputation: 15813

int **matrix = (int **)malloc(n*sizeof(int));

It should be

int **matrix = malloc(n*sizeof(int*));

In your architecture it happens that sizeof(int) and sizeof(void*) do not have the same values.

No need to cast the output of malloc, as void* can correctly behave as any other pointer to object.

Upvotes: 1

Related Questions