二维数组结构段错误

Posted

技术标签:

【中文标题】二维数组结构段错误【英文标题】:2d array struct seg fault 【发布时间】:2014-10-02 08:21:36 【问题描述】:

我是否正确分配了我的结构?如果是这样,那么为什么在第一个元素之后发生段错误。我对整个指针和使用结构解引用感到非常困惑。

问题:

    结构体a的2x2矩阵

    包含这些行的文件 fp

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

相关代码:

结构

typedef struct num
      int s;
num_t;

在使用 a 的 main 中(注意 n 和 m 是整数,在我的运行时是: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));

发生段错误的函数(跳到内部循环的中间):

 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;
 

编辑: 忽略 w 和 z

在运行时我有这个:

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:

抱歉,我发布了来自 2 个不同项目的代码。 num_t 是 typedef 结构,我在粘贴时遇到了问题,因为 putty 复制了我的文件

EDIT3:

格式和成品

#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;

主要:

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

结论

2D struct 数组与 2D int 数组不同。不要在这种类型的函数中传递结构的地址。

【问题讨论】:

请正确缩进您的代码,并发布一个可编译的独立最小示例。您发布的结构甚至没有t 字段,并且您没有向我们展示complexnum_t 是什么。这个问题无法回答。 您在检查失败的malloc 之前取消引用a - 您应该使用a 检查之前。另外,不需要将&amp;a 传递给matrix,它应该使用num_t **a if(fp == NULL) fclose(fp); :删除fclose(fp); 【参考方案1】:

当您调用matrix() 时,您传递了a地址。如果您将num_t ** 视为Matrix_t 类型,那么您将指针传递给 Matrix_t

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

matrix()里面:

int matrix(int n, int m, num_t ***a, char* file)

  ...
  a[i][j]->s = d; //segfaults here

这里,当i 变为1 时,您正在尝试访问下一个Matrix_t,但您只传递了一个指向单个Matrix_t 的指针>。为了使这项工作,您必须在索引元素之前取消引用指针。例如:

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

或者,更好的是:传递a 而不是&amp;a,并将函数定义更改为使用双指针而不是三指针。请注意,您还需要将-&gt; 更改为.。可能还有其他必要的更改;我没有仔细研究你的代码。

【讨论】:

【参考方案2】:

你应该有:

malloc(sizeof(num_t));

指针符号只会给你 4 个字节,因此内存错误。

【讨论】:

【参考方案3】:

而不是

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

这样的代码可以工作。

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

【讨论】:

请考虑扩展此答案。目前还不清楚,对未来的用户帮助不大。 编辑了答案。对不起超短版 @Nish 我没听懂,你的意思是“a[i][j]->s = d”吗?此外,p 来自哪里/您将如何在完成的代码中对其进行初始化。

以上是关于二维数组结构段错误的主要内容,如果未能解决你的问题,请参考以下文章

传递二维结构数组

动态二维数组。为啥是分段错误?

c语言,用二维数组解决迷宫问题。来段完整的代码吧。

PHP二维数组的引用赋值容易犯的错误

C# CS结构中 2005 如何将二维数组转化成DataSet

C 语言二级指针作为输入 ( 二维数组 | 二维数组遍历 | 二维数组排序 )