fscanf()导致分段错误

时间:2015-07-14 18:29:09

标签: c segmentation-fault scanf

我在C中编写一些代码来读取数组中的一些文件数据并继续使用gcc编译分段错误。它读取文件到第11行数据然后给出错误。在这里经历了一些其他类似的问题,但无法找到解决方案。 感谢

代码:

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

int ainb(char a[],char b[])//returns 0 if str b contains a returns 1 otherwise
{
    int i=0,j0=-1,j1=0,count=0;
    if(strlen(b)<strlen(a)) {return 1;}
    for(i=0;i<strlen(b);i++) {
        if((b[i]==a[j1])&&(j1==j0+1)){
            j0=j1;j1++;
        } else {
            j0=-1;j1=0;
        }
        if((j1+1)==strlen(a)) {break;}
    }
    if((j1+1)==strlen(a)){
        return 0;
    } else {
        return 1;
    }
}

void read_pdb(FILE* fp,char **atm,int *atnum,char **name,char **res,char *chain,int *resnum,double *x,double *y,double *z,double *occ,double *bfac,char **elem,double ac[2][3])  //reads file lines and stores in arrays
{
    printf("\nReading pdb data\n");
    int i=0,j=0;
    char buff[7];
    fpos_t position;

    while(!feof(fp))
    {

        fgetpos(fp,&position);fgets(buff,sizeof buff,fp);
        if((ainb("ATOM",buff)==0)||(ainb("HETATM",buff)==0))
        {
            fsetpos(fp,&position);printf("\ngetting position %d\n",i+1);
            fscanf(fp,"%6s%5d %4s %3s %1s%4d %8lf%8lf%8lf%6lf%6lf %2s \n",atm[i],&atnum[i],name[i],res[i],&chain[i],&resnum[i],&x[i],&y[i],&z[i],&occ[i],&bfac[i],elem[i]);
            printf("\nnode %d data found\n",i+1);
            printf("\n%6s%5d %4s %3s %1s%4d    %8.3lf%8.3lf%8.3lf%6.2lf%6.2lf          %2s  \n",atm[i],atnum[i],name[i],res[i],&chain[i],resnum[i],x[i],y[i],z[i],occ[i],bfac[i],elem[i]);
            if(ainb("HETATM",atm[i])==0){
                ac[j][0]=x[i];ac[j][1]=y[i];ac[j][2]=z[i];j++;
            }
            i++;
        }
    }
    printf("\n%d Atoms read\n",i);
}

void main()
{
    double ac[2][3];
    int N,k;

    double *x,*y,*z,*occ,*bfac;
    char **atm,**name,**res,**elem,*chain;
    int *atnum,*resnum;
    FILE *out;

    out=fopen("OUT.pdb","r");//something to check for file
    N=66;

    //make dynamic arrays
    x=(double*)malloc(N*sizeof(double));
    y=(double*)malloc(N*sizeof(double));
    z=(double*)malloc(N*sizeof(double));
    occ=(double*)malloc(N*sizeof(double));
    bfac=(double*)malloc(N*sizeof(double));
    atnum=(int*)malloc(N*sizeof(int));
    resnum=(int*)malloc(N*sizeof(int));
    atm=(char**)malloc(N*sizeof(char));
    name=(char**)malloc(N*sizeof(char));
    res=(char**)malloc(N*sizeof(char));
    elem=(char**)malloc(N*sizeof(char));
    chain=(char*)malloc(N*sizeof(char));
    for(k=0;k<N;k++)
    {
        atm[k]=(char*)malloc(7*sizeof(char));
        name[k]=(char*)malloc(5*sizeof(char));
        res[k]=(char*)malloc(4*sizeof(char));
        elem[k]=(char*)malloc(3*sizeof(char));
    }
    //read in data
    read_pdb(out,atm,atnum,name,res,chain,resnum,x,y,z,occ,bfac,elem,ac);
    fclose(out);

    printf("\n-------------------------------------------\nTest Complete\n");
    free(x);
    free(y);
    free(z);
    free(occ);
    free(bfac);
    free(elem);
    free(name);
    free(atm);
    free(res);
    free(resnum);
    free(atnum);
    free(chain);
}

输出结果为:

Reading pdb data

getting position 1

node 1 data found

  ATOM    1   CA PRO A   1       4.612   0.903   5.089  1.00 24.97           C  

getting position 2

node 2 data found

  ATOM    2   CA SER A   2       3.526   0.341   3.809  1.00 59.99           C  

getting position 3

node 3 data found

  ATOM    3   CA ARG A   3       6.208   1.550   6.551  1.00 20.40           C  

getting position 4

node 4 data found

  ATOM    4   CA TRP A   4       5.912   2.348   4.388  1.00 50.28           C  

getting position 5

node 5 data found

  ATOM    5   CA GLE A   5       4.087   4.359   6.884  1.00 54.04           C  

getting position 6

node 6 data found

  ATOM    6   CA THR A   6       4.405   1.292   2.566  1.00 62.06           C  

getting position 7

node 7 data found

  ATOM    7   CA TYR A   7       3.327   3.041   5.205  1.00 50.46           C  

getting position 8

node 8 data found

  ATOM    8   CA VAL A   8       5.276   0.109   0.387  1.00 58.00           C  

getting position 9

node 9 data found

  ATOM    9   CA LEU A   9       2.992   3.190   3.084  1.00 41.48           C  

getting position 10

node 10 data found

  ATOM   10   CA CYS A  10       3.565   0.287   0.721  1.00 47.65           C  

getting position 11
Segmentation fault (core dumped)

2 个答案:

答案 0 :(得分:1)

让我们考虑一下这段代码:

name=(char**)malloc(N*sizeof(char));
for(k=0;k<N;k++)
{
    name[k]=(char*)malloc(5*sizeof(char));
}

您分配n*sizeof(char)数组并尝试将N指针存储到其中char。但是指向char的指针大小大于sizeof(char),因此即使在初始化阶段也会出现缓冲区溢出和未定义的行为。你很幸运,你的程序在这个阶段没有崩溃,但它会在阵列使用上失败。要防止出现此错误,您应在分配代码中使用sizeof(char*)

答案 1 :(得分:0)

不是硬编码类型,而是为name弄错,让编译器搞清楚。更少的代码,更易于阅读,更容易编码和维护。

//bfac=(double*)malloc(N*sizeof(double));
//resnum=(int*)malloc(N*sizeof(int));
//name=(char**)malloc(N*sizeof(char));  OP was looking for `sizeof (char*)`

bfac   = malloc(N * sizeof *bfac);
resnum = malloc(N * sizeof *resnum);
name   = malloc(N * sizeof *name);

同样在C中,无需转换malloc()的结果。