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