我在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)
答案 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()
的结果。