2015-07-14 4 views
-3

Я пишу код на C, чтобы прочитать некоторые данные файла в массивах и продолжать собирать ошибку сегментации с помощью gcc. Он считывает файл до 11-й строки данных, затем выдаёт ошибку. Были некоторые другие подобные вопросы здесь, но не могут найти решение. Благодаряfscanf(), вызывающий ошибку сегментации

код:

#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) 
+0

Итак, как выглядит 11-я строка вашего файла? Есть ли у него один? Кроме того, вы должны действительно проверить возврат из 'fscanf()', чтобы убедиться, что он успешно прочитал все поля. – Dmitri

+0

11-я строка: ATOM 11 CA VAL A 11 4.835 4.291 0.185 1.00 38.80 C – lsaw

+0

только что поставил чек и возвращает 12, как и ожидалось, до тех пор, пока он не даст ошибку – lsaw

ответ

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 в этом. Но размер указателя на символ больше sizeof(char), поэтому вы получаете переполнение буфера и неопределенное поведение даже на этапе инициализации. Вам повезло, и ваша программа не рушится на этом этапе, но она не будет работать при использовании массива. Чтобы предотвратить эту ошибку, вы должны использовать sizeof(char*) в вашем коде распределения.

+0

Как глупо меня. Это работает. Спасибо за помощь – lsaw

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().

Смежные вопросы