0

I'd like to fill and print a static matrix, for sorting then with the Young Tablue proprieties Here, but I have a problem with some dimension (row and col) input, with some input show me the right matrix, but with others give me seg.fault or a weird output. Here the function:

#include <stdio.h>
#include <stdlib.h>
#define MAX 32

void fill( int A[MAX][MAX], int numRig, int numCol, int numElem){
 int i,j; 
 int count = 0; 

 for ( i = 0 ; i < numRig; i++ ) {

     for ( j = 0 ; j < numCol; j++) {




             A[i][j] = rand() % 20;
            //fscanf(stdin,"%d", &A[i][j]);
             //DEBUG
             printf("%d\n", A[i][j]);

    }
 }

 }

void stamp(int A[MAX][MAX], int numRig, int numCol){
int k,h;

  for ( h = 0 ; h < numRig; h++ ) {

     for ( k = 0 ; k < numCol; k++) {


            printf("%d ", A[h][k]);
        }
        printf("\n");
    }
 }

the main

 int main () {
   int row,col;
   printf("Insert row and col:\n");
   scanf("%d %d", &row, &col);
   int A[row][col];
   fill(A,row,col);
   stamp(A,row,col);
   return 0;
}

output with row=4 and col=4: "3 6 17 15 -1 0 0 0 2017675728 32765 -741456064 21906 -1 0 0 0 2017675728 32765 -741456064 21906 0 0 -741454033 21906 2017675728 32765 -741456064 21906 0 0 -741454033 21906 4 0 0 0 0 0 -741454033 21906 4 0 0 0 2017675976 32765 2017675552 32765 4 0 0 0 2017675976 32765 2017675552 32765 3 0 0 0 2017675976 32765 2017675552 32765 3 0 0 0 4 0 0 0 "

I tried with dynamic allocation: a=(int**)malloc(row*(sizeof(int*))); for(i=0;i<row;i++) a[i]=(int*)malloc(col*sizeof(int));

and all works fine, but I must use static allocation.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
JimMinor9
  • 11
  • 4
  • You SHOULD allocate your matrix before trying to use it, and this is done using at least int A[MAX][MAX] in your main – Gar Mar 31 '17 at 13:20
  • Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example. – too honest for this site Mar 31 '17 at 13:21
  • i allocate the matrix in this way: int row,col; int A[row][col]; fill(A,row,col); stamp(A,row,col); – JimMinor9 Mar 31 '17 at 13:22
  • `int row,col; int A[row][col];` row and col must be initialized before you declare the array. And this crap `a=(int**)malloc(row*(sizeof(int*)))` is not even an multi-dimensional array. – Lundin Mar 31 '17 at 13:31
  • 1
    [Correctly allocating multi-dimensional arrays](http://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays). – Lundin Mar 31 '17 at 13:32
  • You have allocated a 1-dimensional array of pointers, with each element pointing to a 1-dimensional array of int. But your functions work on 2-dimensional arrays of int. They are not the same thing. – Ian Abbott Mar 31 '17 at 13:33
  • You could change your functions to use `int **A`, then it would work with your array of pointers to arrays of int. – Ian Abbott Mar 31 '17 at 13:35
  • I must use static allocation, with int **A all work fine. – JimMinor9 Mar 31 '17 at 13:59

1 Answers1

1

Because the address of A[i][j] is by definition &A[0][0] + i * cols + j where cols is the declared number of columns of the matrix.

So if you declare the matrix as int A[4][4] in the main, you only reserve memory for 16 ints. But as you use it as int A[32][32] in your functions address of A[3][0] is 60 places after A[0][0] so far beyond the allocated array => you just invoke Undefined Behaviour

You must declare the matrix in main as int A[MAX][MAX];, you can then safely only use first rows and first columns as long as the matrix is declared with same dimensions in main and all the functions.


Variable Length Array can also be a nice alternative here (thanks to Jonathan Leffler for suggesting this). They are supported in C99, and are optionally supported since C11, but all major recent C compilers accept it, even if MSVC support is fairly recent.

That means that you can still declare int A[row][col]; in main, but your function declaration must become:

void fill( int numRig, int numCol, int A[numRig][numCol]){
...
}
void stamp(int numRig, int numCol, int A[numRig][numCol]){
...
}

The variable length array shall be declared after its dimension in the function declaration.

But now as the declared dimensions of the matrix are consistent throughout the program, no undefined behaviour is involved...


According to the standard anyway, simply aliasing a matrix or a simple array to a matrix or array of a different size is undefined behaviour.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252