【问题标题】:C program received signal SIGSEGV, Segmentation fault at matrix-multiplication?C程序收到信号SIGSEGV,矩阵乘法时出现分段错误?
【发布时间】:2017-10-22 11:43:49
【问题描述】:

是的,我已经阅读了这样的问题,但没有一个证明对我的问题有用。我的程序有一个问题,该功能在另一个程序中运行良好。

程序收到信号SIGSEGV,分段错误。 _int_malloc (av=0x7ffff7dd8e40, bytes=32) at malloc.c:4703 4703 malloc.c: 没有这样的文件或目录。

这是我收到的错误。

这是我的程序:

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

void endl()
{
  printf("\n\n");
}

void loadVector(FILE *infile, double *vector, int col)
{
  int i;
  for(i=0;i<col;i++)
  {
    fscanf(infile,"%lf",&vector[i]);
  }
  printf("vector read...\n");
}

void printVec(double *vect, int run)
{
  int k;
  for(k=0;k<run;k++)
  {
   printf("%.2f ",vect[k]);
  }
}

double* duplic(double* matr, double *vect, double *sol,  int col, int  row)
{
  int k, l;
  for(k=0;k<row;k++)
  {
    for(l=0;l<col;l++)
    {
      sol[k] += matr[col*k+l] * vect[l];
    }
  }
  return sol;
}


int main(int argc, char **argv)
{
  endl();
  printf("=== ===");
  endl();

  if(argc!=3)
  {
    perror("not enough arguments");
    endl();
    return 1;
  }

  char ins[300];
  char *cut;
  int row=0, col=0, rnr = 1, index = 0;
  double temp;
  double *mat = NULL;
  double *vec = NULL;
  double *res = NULL;

  FILE *in;
  in = fopen(argv[1], "r");

  while(fgets(ins,sizeof(ins),in) != NULL)
  {
      col = 0;
      cut = strtok(ins," ");
      while(cut != NULL)
      {
        col++;
        sscanf(cut,"%lf",&temp);
        if(mat==NULL)
         {
            mat = malloc(sizeof(temp));
            *mat = temp;
         }
         else
         {
            rnr ++;
            mat = realloc(mat,sizeof(mat)*rnr);
            index = rnr - 1;
            *(mat+index)=temp;
         }
        cut = strtok(NULL," ");
    }
    row ++;
 }

fclose(in);

printf("Matrix read...");
endl();

printf("Printing matrix: ");
endl();

int i, j;
for(i=0;i<row;i++)
{
   for(j=0;j<col;j++)
   {
      printf("%.2f ",mat[col*i+j]);
   }
   printf("\n");
}
endl();

// printf("rows: %i\tcols: %i\n",row,col);

vec = malloc(sizeof(col));

FILE *inv;
inv = fopen(argv[2],"r");
loadVector(inv,vec,col);

endl();
printVec(vec,col);
endl();

res = malloc(sizeof(row)); 
res = duplic(mat,vec,res,col,row);

printf("Solution-vector calculated...");
endl();
printf("\nSolution vector:");
endl();

printVec(res,row);

endl();

free(mat);
free(vec);
free(res);
fclose(inv);

printf("Exitting\n");
return 0;
}

该程序是一个矩阵-向量乘法程序,它读取一个未知大小的矩阵和一个匹配向量(另外,如果您可以提供更好的方法来读取具有更好代码的随机长度行,我'会很高兴)。 问题出在乘法代码上——尽管它应该可以工作,就像我写的另一个程序一样,它的大小是固定的。 所以它很好地读取了矩阵和向量,然后给出了段错误。

有什么想法吗?

【问题讨论】:

  • 你应该做一些调试 - Valgrind 在这里会是一个很好的帮助(假设它是你平台上的一个选项)。
  • 有趣的是,当我使用 Valgrind 运行它时,它没有出现任何问题并按预期运行。正常跑的时候又死了。

标签: c matrix malloc segmentation-fault


【解决方案1】:

您写了sizeof(col),但col 是一个整数,这意味着您的vec 数组将始终分配sizeof(int) 字节的内存(通常为4 字节,但取决于您的架构)。如果你想要一个包含双精度数的双精度数组,你想使用malloc(sizeof(double) * col) 来分配正确的字节数。

我怀疑您的 res 数组也出现了同样的问题。它可能在某些情况下有效,在您分配的空间之后的空间仍然可用于写入的情况下,在这种情况下计算机不会抱怨,因为 malloc 的内存都在堆中。但是,如果碰巧您尝试在 malloc'ed 块(太小)之后写入受保护或保留的内存部分,操作系统将抛出 SegFault。

【讨论】:

  • Aaa 并且修复了它......该死的。感谢您提供快速有用的答案!
  • 没问题,您可能想查看代码中的其他一些 malloc。我认为你的 res 需要是col * row * sizeof(double)
  • "4 字节内存(整数的大小)" 1) 有多种整数类型。假设你的意思是int:这不能保证。 int 可以是 1 字节以内的任意大小。
  • @Olaf 你说 int 可以是 1 字节以内的任意大小
  • @FelixGuo 是的,我把它改成了 sizeof(double)*row :) 再次感谢你的帮助!
猜你喜欢
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多