2012-01-01 41 views
3

我希望实现一个简单的分子动力学程序。我的第一步是将系统定义为一系列原子,每个原子都有一个类型,一个id号,一个​​3维位置矢量和一个3D速度矢量。下面是我写这样做的程序:代码最后一行的Seg错误

FILE *init; 

static int randomVelocity(void) 
{ 
    return rand()/RAND_MAX - 0.5; 
} 


int main(int argc, char *argv[]) 
{ 

    int iType; 
    int iID; 
    int i; 
    double* pdPosition; 
    double* pdVelocity; 
    char* line; 
    Atom* poAtoms; 
    int count = 0; 

    init = fopen("newdat.txt", "r+"); 
    srand((unsigned)time(NULL)); 
    line = malloc(81*sizeof(char)); 
    while (fgets(line, 80, init) != NULL)  
    { 
     char* tok1; 
     char* tok2; 
     char* tok3; 
     char* tok4; 
     tok1 = strtok(line, " \t"); 
     if ((tok1 == NULL) || (tok1[0] == '*')) 
     { 
       break; 
     } 
     tok2 = strtok(NULL, " \t"); 
     tok3 = strtok(NULL, " \t"); 
     tok4 = strtok(NULL, " \t"); 
     iType = atoi(tok1); 
     iID = count; 
     pdPosition = (double*)malloc(3*sizeof(double)); 
     pdVelocity = (double*)malloc(3*sizeof(double));  
     pdPosition[0] = atof(tok2); 
     pdPosition[1] = atof(tok3); 
     pdPosition[2] = atof(tok4); 
     pdVelocity[0] = randomVelocity(); 
     pdVelocity[1] = randomVelocity();  
     pdVelocity[2] = randomVelocity(); 
     poAtoms[count] = Atom_new(iType, iID, pdPosition, pdVelocity); 
     count++; 
    } 

    for (i = 0; i < count; i++) 
    { 
     Atom_print(poAtoms[i]); 
     Atom_free(poAtoms[i]); 
    } 

    free(line); 
    return 0; 
} 

这里是头文件atom.h:

/**** atom.h ****/ 


typedef struct Atom_str *Atom; 

Atom Atom_new(int iType, int iID, double* adPosition, double* adVelocity); 

void Atom_free(Atom oAtom); 

void Atom_print(Atom oAtom); 

和测试输入文件:

1 5 7 9 
2 12 13 14 

程序编译,但是当我运行它时,我会得到期望的输出,然后是seg故障。我正在使用GDB调试器,在return语句之后,seg错误似乎发生在最后一行代码中!这是内存管理问题吗?

+0

这些类型的问题通常与内存损坏有关。你可以在GDB崩溃后输入“bt”,看看是否有堆栈跟踪,如果是这样的话就发布它?或者使用Valgrind。 – 2012-01-01 20:07:04

+0

这是您所指的堆栈跟踪? #0 0x0804b3fd在?? () #1 0x00000001在? () #2 0xffffd8b4在? () #3 0xffffd8bc在? () #4 0x00722828在? () #5 0x00000000在? () – user1125353 2012-01-01 21:06:36

回答

6

你从来没有malloc ed内存poAtoms。写入到未初始化的指针点的地方很容易导致段错误。

你开始读文件之前,您应该分配一定的空间,

unsigned expected_count = 2; // for the test input file, would be much larger in real runs 
poAtoms = malloc(expected_count*sizeof(*poAtoms)); 

然后你必须检查你不写过去所分配的内存读循环​​中。之前

poAtoms[count] = Atom_new(iType, iID, pdPosition, pdVelocity); 

插入一张支票,

if (expected_count <= count) 
    { 
     expected_count *= 2; // double the space, could also be a smaller growth factor 
     Atom *temp = realloc(poAtoms, expected_count*sizeof(*poAtoms)); 
     if (temp == NULL) 
     { 
      perror("Reallocation failed, exiting\n"); 
      exit(EXIT_FAILURE); 
     } 
     poAtoms = temp; 
    } 

如果poAtoms分配的空间已被使用,尝试用realloc得到更多,如果失败,中止,除非你知道如何解决它。如果重新分配成功,我们可以继续收集新的原子。

+0

谢谢你的回复,丹尼尔!我正在为我的原子提供代码。c文件:struct Atom_str { int iType; int iID; double * pdPosition; double * pdVelocity; }; Atom Atom_new(int iType,int iID,double * adPosition,double * adVelocity) {Atom oAtom; oAtom =(Atom)malloc(sizeof(struct Atom_str)); if(oAtom == NULL) return NULL; oAtom-> iType = iType; oAtom-> iID = iID; oAtom-> pdPosition = adPosition; oAtom-> pdVelocity = adVelocity; return oAtom; } – user1125353 2012-01-01 20:51:35

+0

对不起,这里有奇怪的格式...但我的意思是说我使用行“oAtom =(Atom)malloc(sizeof(struct Atom_str))”为原子结构做了malloc空间;我可能没有足够的记忆吗? – user1125353 2012-01-01 20:54:51

+0

呃,这里没什么关系,因为在声明'Atom * po'和'poAtoms [count] = Atom_new(iType,iID,pdPosition,pdVelocity)'之间,'没有提到'poAtoms'。所以'poAtoms'指向意外占据堆栈位置的位,并且这就是'Atom_new'的返回值被写入的位置。在你的情况下,这似乎已经覆盖了程序退出代码的一部分。 – 2012-01-01 21:03:11

0

tok1 [0]在if条件下做什么?你是否检查了strtok的一个小代码片段,当你尝试打印tok1 [[0]时返回或检查了什么?

0

你能解释1 5 7 9在输入文件中代表什么吗?是我的类型id和速度。 如果是这样,你可以通过连字符来操作和区分它们,并通过strtok将每个值提取为NULL。还要检查fgets是否追加了NULL,或者可能是*,因为您试图检查条件是否可能为行尾。我有一个感觉,它可能是你错误的地方,或者如果你可以请求解释你的输入文件,这将是有帮助的

+0

感谢您的回复! 1是原子类型; 5,7和9应分别是位置矢量的x,y和z分量。 (速度矢量的三个分量由随机数发生器提供。)我的代码的if(tok1 [0] =='''')部分应该让我的输入文件有注释,由'*'分隔。 ..但我可能需要通过更多的想法! :) – user1125353 2012-01-01 20:49:38