【问题标题】:Segmentation Fault in Passing String Literal as Argument in C在 C 中将字符串文字作为参数传递时的分段错误
【发布时间】:2018-09-16 04:24:38
【问题描述】:

我试图编写一个程序来使用 C 中的 OpenMP 执行矩阵乘法。每当我尝试将字符串文字作为参数传递给函数时,都会遇到分段错误错误。

#include<stdio.h>
#include<time.h>
#include<omp.h>

struct matrix{
    int r;
    int c;
    int mat[1000][1000];
};

void read_matrix(char* fname, struct matrix* m){
    FILE *fp;
    fp = fopen(fname,"r");

    fscanf(fp, "%d %d",&m->r,&m->c);
    for(int i=0;i<m->r;i++){
        for(int j=0;j<m->c;j++){
            fscanf(fp, "%d", &m->mat[i][j]);
        }
    }
    fclose(fp);
}

void write_matrix(char* fname, struct matrix m){
    FILE *fp;
    fp = fopen(fname,"w");
    fprintf(fp,"%d %d\n",m.r,m.c);
    for(int i=0;i<m.r;i++){
        for(int j=0;j<m.c;j++){
            fprintf(fp,"%d\n",m.mat[i][j]);
        }
    }
    fclose(fp);
}

void main(){
    struct matrix m1;
    struct matrix m2;
    struct matrix res;
    read_matrix("m1",&m1);
    read_matrix("m2",&m2);
    int r1 = m1.r;
    int c1 = m1.c;
    int c2 = m2.c;
    res.r = r1;
    res.c = c2;
    for(int i=0;i<r1;i++){
        for(int j=0;j<c2;j++){
            res.mat[i][j] = 0;
        }
    }
    #pragma omp parallel
    {
        #pragma omp for
        for(int i = 0; i < r1; i++){
            for(int j = 0; j < c2; j++){
                for(int k = 0; k < c1; k++){
                    #pragma omp atomic update
                    res.mat[i][j] += m1.mat[i][k]*m2.mat[k][j];
                }
            }
        }
    }
    write_matrix("res",res);

}

代码在运行时显示Segmentation fault (core dumped)。 在 GDB 上运行时,它显示 Program received signal SIGSEGV, Segmentation fault. 0x0000000000400ad9 in main () at mm.c:40 40 read_matrix("m1",&m1); 在第一次 read_matrix() 调用之前,我添加了一条 printf 语句 printf("check\n"); printf 调用现在开始引发分段错误。 我假设传递字符串文字是错误的原因。代码可能有什么问题?

【问题讨论】:

  • 你检查fopen()的返回值了吗?
  • 结构矩阵在 64 位上有 7 兆字节。 ulimit -sulimit -a 在您的系统上的输出是什么?你的系统是 64 位的吗?
  • 您没有检查m-&gt;rm-&gt;c 是否低于1000,任何高于1000 的值都可能导致越界访问和段错误。
  • 对,m-&gt;rm-&gt;c 的值是否低于 1000?你能显示示例输入吗?什么是预期的输出? (struct matrix)-&gt;mat 是一个小数组,比如mat[10][10],这是否会发生?
  • 看起来 Afshin 解决了这个问题。 main() 保留的堆栈空间多于可用空间,一旦您尝试调用任何函数并开始将参数数据推送到堆栈边界之外,程序就会崩溃。您需要动态分配这些结构,或将它们设为全局,或将它们设为static,以将它们移出堆栈。在本地分配的这个大小的变量是不行的。

标签: c


【解决方案1】:

在第一个 read_matrix() 调用之前,我添加了一条 printf 语句 printf("check\n"); printf 调用现在开始抛出分段 故障。

我认为这可能是因为您在堆栈上分配了struct matrix。每个矩阵大约 4MB,所以堆栈上有 12MB。我猜它会创建站点(堆栈溢出)。

尝试对矩阵使用静态变量或动态分配它们。它可能会解决您的问题。如果没有,永远不要在堆栈上分配 12MB 的结构......

【讨论】:

  • 有道理,stack 通常只能处理 1MB。这些结构肯定会导致问题。
  • Stack 在现代 linux 机器上最多可以处理ulimit -s。最大堆栈大小取决于系统。
  • @KamilCuk 是的,但他没有说明他的系统限制。而且我认为默认值不会达到 12MB....
  • @KamilCuk 最后我检查了它是由编译器指定的,你实际上可以决定你希望你的程序有多少堆栈,至少在 Windows 上是这样。系统不必知道堆栈或任何其他虚拟内存空间之间的区别,只要有写访问权限,它就应该可以正常工作。
  • @Havenard 它由链接器指定,并且限制存储在可执行文件头中,以便加载器可以创建所需的初始进程/线程环境/限制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-13
  • 1970-01-01
  • 2012-06-03
相关资源
最近更新 更多