John Wick
John Wick

Reputation: 37

Segmentation Fault for 2d array in C

The orange crosses are made from 'G' of the matrix and are valid. Blue ones are made from 'B' and are invalid

The following code is for finding the 2 maximum areas of cross possible with equal lengths of hand from a 2D array(made from 'G' and 'B'.). The cross should be made up of 'G.' THe following code is giving me segmentation fault while/after scanning the 2D Matrix. Please help!!

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

int main() {
int i,j,k,l,p,q;
char M[10][10];
int m, n;
int min=0;
int rl=0;
int max1=1;
int max2=1;
int area;
int tarea;
int cu=0;
scanf("%d",&n);
scanf("%d",&m);
//matrix scan
for(i=0;i<n;i++){
  for(j=0;j<m;j++){
    scanf("%c",&M[i][j]);

  }
}
 // finding first cross

for(i=0;i<n;i++){
   for(j=0;j<n;j++){
     k=j;
     l=k;
    p=i;
    q=i;
    while(M[i][k]!='B' || M[i][l]!='B' || l!=m || k!=0){
        k--;
        l++;
        rl++;
    }

    while(M[p][j]!='B' || M[q][j]!='B' || p!=0 || q!=n){
        p--;
        q++;
        cu++;
    }
    if(rl>cu){
    min=cu;
    }
    else
    min=rl;
    area=min*4+1;
    if(area>max2){
    max2=area;
    }
    if(area>max1){
    max1=area;
    }

    }
  }

tarea=max1+max2;
printf("%d",tarea);

return 0;
}

Upvotes: 1

Views: 578

Answers (1)

John Bollinger
John Bollinger

Reputation: 180058

Your two while loops can very easily produce an out-of-bounds access to array M. Consider, for example ...

while(M[i][k]!='B' || M[i][l]!='B' || l!=m || k!=0){
    k--;
    l++;
    rl++;
}

... on the first pass through the containing loop, where i, k, and l are all initially zero. Suppose further that M[0][0] has a value different from 'B'. The body of the loop will then be executed, resulting in k taking the value -1, and then the control expression evaluated again, resulting in an attempt to read the value of M[0][-1]. The result is undefined, but a segmentation fault -- then or later -- is entirely plausible.

You need to do your bounds tests first, and you need to use && rather than || to ensure that the loop in fact exits when the bounds are reached. It's not immediately clear to me what you want to do exactly on the edge, but here's the general idea:

while((k > 0) && (l < m) && (M[i][k] != 'B' || M[i][l] != 'B')) {
    k--;
    l++;
    rl++;
}

Similar applies to your other while loop.

Those are not the only issues, but they are probably the ones responsible for the behavior you asked about.

Upvotes: 1

Related Questions