Ошибка сегмента в последней строке кода - PullRequest
3 голосов
/ 02 января 2012

Я надеюсь реализовать простую программу молекулярной динамики.Мой первый шаг - определить систему как последовательность атомов, каждый из которых имеет тип, идентификационный номер, трехмерный вектор положения и трехмерный вектор скорости.Ниже приведена программа, которую я написал для этого:

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  

Программа компилируется, но когда я ее запускаю, я получаю ожидаемый результат, за которым следует ошибка сегмента.Я использую отладчик GDB, и ошибка seg возникает в самой последней строке кода после оператора return!Это проблема управления памятью?

Ответы [ 3 ]

6 голосов
/ 02 января 2012

Вы никогда не malloc редактировали память для poAtoms.Запись туда, где эти неинициализированные точки указателя могут легко вызвать ошибку segfault.

Прежде чем вы начнете читать файл, вы должны выделить некоторое пространство,

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 голосов
/ 02 января 2012

Можете ли вы объяснить, что 1 5 7 9 представляет во входном файле? их тип id и скорость. Если это так, вы можете манипулировать и дифференцировать их по дефису и извлекать каждое значение по strtok как NULL. Также проверьте, если fgets добавляет NULL или может быть *, как вы пытались проверить, возможно ли условие для конца строки. У меня есть ощущение, что это может быть то место, где вы идете не так, или, если вы можете, пожалуйста, объяснить ваш входной файл, это будет полезно

0 голосов
/ 02 января 2012

Что делает tok1 [0] в условии if?Вы проверяли небольшой фрагмент кода для strtok, что возвращено или проверено, когда вы пытаетесь напечатать tok1 [[0]?

...