简体   繁体   中英

2d array struct seg fault

Am I mallocing my struct correctly? If so then why is a segfault occurring after the first element. I am quite stumped on the whole pointer and dereferencing with structs.

The problem:

  1. 2x2 matrix of struct a
  2. file fp containing the lines

     5 4 3 2 1 1 11 21 1 3 2 2 

Relevant code:

struct

typedef struct num{
      int s;
}num_t;

In main that uses a (note n and m are ints, where in my runtime were: n = 2, m = 3)

num_t **a;
a =  malloc(sizeof(num_t *) * n);
for(i=0;i<n;i++)
    a[i]=  malloc(sizeof(num_t) * m);

//check if mallocs suceeded
if(a==NULL)
    return -1;

//read matrix.dat, check if correct size
pb = matrix(n,m,&a,*(argv+3));

My function where segfault occurs(skip to the middle of inner loop):

 int matrix(int n, int m, num_t ***a, char* file)
 {
 int i,j,k,count;
 int d,e;
 char z,w;
 FILE *fp;

      fp = fopen(file,"r");
      //check if file opened
      if(fp == NULL)
      {
              fclose(fp);
              return -1;
      }
      else
      {
              i=0;
              k=0;
              count=0;
              for(i=0;(k!=EOF)||i<n;i++)
              {
                      printf("n=%d , m=%d\n",n,m);fflush(stdout);
                      for(j=0;j<m;j++)
                      {
                          //printf("Innit i=%d j=%d\n",i,j);fflush(stdout);
                          k=fscanf(fp,"%d",&d);
                          if(k!=1){
                             j++;break;
                          } 
                          //printf("fscan1 passed\n");fflush(stdout);
                          k=fscanf(fp,"%d",&e);
                          if(k!=1){
                              j++;break;
                          }
                          printf("fscanf2 passed\n");fflush(stdout);//prints

                          a[i][j]->s = d; //segfaults here
                          printf("dpassed\n");fflush(stdout); //doesnt print

                          a[i][j]->t = e;
                          //printf("dpassed\n");fflush(stdout);
                          if(j==m-1){
                              count++;
                              //printf("enter break\n");fflush(stdout);
                          } 

                          count++;
                          //printf("out j a[%d][%d] = %d and %d k=%d\n",i,j,a[i]      [j]->s,a[i][j]->t,k);fflush(stdout);
                     }
               //printf("enter out i=%d\n",i);fflush(stdout);
             }
             //printf("brokenout");fflush(stdout);
             if((k = fscanf(fp,"%lf",&d)) >0)
                    count++;
             fclose(fp);

            //check matrix sizes
            if((i!=n) || j!=m-1 || count!=(n * m))
                 return -1;
     }
     return 1;
 }

EDIT: Disregard w and z

At run time I had this:

n=1 , m=3
Innit i=0 j=0
fscan1 passed
fscanf2 passed
a[0][0] = 0 and 0 k=1 w='' z=''
dpassed
dpassed
out j a[0][0] = 5 and 4 k=1
Innit i=0 j=1
fscan1 passed
fscanf2 passed
[1]    13367 segmentation fault

EDIT2:

Sorry I had posted code from 2 different projects. num_t is the typedef struct, I had issues editing my code when I pasted because of how putty copied my files

EDIT3:

Format and the finished product

#include "header.h"//contains struct

int read_matrix(int row, int col, num_t** a, char* file)
{
int i,j,k,count,d,e;
FILE *fp;

    fp = fopen(file,"r");

    //check if file opened
    if(fp == NULL)
    {
          fclose(fp);
          return -1;
    }
    else
    {
          i=0;
          k=0;
          count=0;
          for(i=0;(k!=EOF)||i<row;i++)
          {
                for(j=0;j<col;j++)
                {
                    k=fscanf(fp,"%d%d",&d,&e);
                    if(k!=2){
                        break;
                    }    
                    a[i][j].s = d;
                    a[i][j].t = e;
                    if(j==col-1){
                         count++;
                    }   
                         count++;
                }
          }
          fclose(fp);

          //check matrix sizes
          if((i!=row) || j!=col-1 || count!=(row * col))
                  return -1;
     }
     return 1;
}

In main:

pb = matrix(m,x,a,*(argv+3));

Conclusion

2D struct arrays are not like 2D int arrays. Don't pass the address of a struct inside this type of function.

instead of

a[i][j]->s = s

a code like this will work.

 p = a[i];
 p[j].s = s;

When you call matrix() , you pass the address of a . If you think of num_t ** as a Matrix_t type, then you are passing a pointer to Matrix_t .

 num_t **a; ... pb = matrix(n,m,&a,*(argv+3)); 

And inside matrix() :

 int matrix(int n, int m, num_t ***a, char* file) { ... a[i][j]->s = d; //segfaults here 

Here, when i becomes 1 , you are trying to access the next Matrix_t , but you only passed a pointer to a single Matrix_t . In order to make this work, you have to dereference the pointer before you index the elements. Eg.:

  (*a)[i][j].s = d; //segfaults here

Or, better yet: Pass a instead of &a , and change your function definition to use a double pointer instead of a triple pointer. Note that you also need to change your -> 's to . 's. There may be other changes that are necessary; I didn't look too far into your code.

You should have:

malloc(sizeof(num_t));

The pointer symbol will only give you 4 bytes, hence the memory fault.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM