0

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);
}
3
  • 1
    int **matrix = (int **)malloc(n*sizeof(int)); --> int **matrix = malloc(n*sizeof(int *)); notice size of a pointer to int and without the cast. Commented Sep 25, 2020 at 15:26
  • 1
    See the above comment. If pointers are larger than integers on your system, which is quite likely, then you aren't allocating enough space for your pointer array, since you're using sizeof(int) where you need sizeof(int *). Commented Sep 25, 2020 at 15:28
  • Dear Op, welcome to S.O. Consider using `` instead of "" to show code AND error messages ... Commented Sep 25, 2020 at 15:40

2 Answers 2

1
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.

Sign up to request clarification or add additional context in comments.

9 Comments

A simple , elegant solution :)
@APJo Actually now I see that somebody already commented it.
Answers are better than comments.
@alinsoar How come void * can implicitly convert to int ** but my char ** can't implicitly convert to a void ** - any real logic behind that or ... ?
|
0
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.