Ошибка сегментации (ядро выгружено) ошибка при чтении файла строка за строкой в ​​C для моей программы моделирования процесса планирования - PullRequest
0 голосов
/ 23 марта 2020

У меня есть программа, которая берет информацию о процессах из текстового файла, а затем использует требуемый алгоритм планирования ЦП для планирования процесса и его соответствующей печати. ​​

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/time.h>
#include<time.h>

//Structure to store the information about a process
typedef struct{

    int pid;
    int arrival;
    int burst;

}Processes;

//Array of structure
typedef struct
{
    Processes *array;
    size_t used;
    size_t size;
} Array;

enum ALGORITHM_TYPE{FCFS, RR, SRTF};                        //enum for creating the algorithm types
int procNum = 0;                                            //Variable to keep track of number of processes
Array proc, fin;


//Function to determine the number of processes
void procNumFunction(char *fileName){

    FILE *fp;                                               //File pointer
    char *buffer, c;

    fp = fopen(fileName, "r");
    if(fp == NULL)
        exit(1);

    // Extract characters from file and store in character c
    for (c = getc(fp); c != EOF; c = getc(fp))
        if (c == '\n') // Increment count if this character is newline
            procNum++;

    printf("\nTotal %d tasks are read from \"%s\"\n\n", procNum, fileName);

}

//function to dynamically fill the array
void initArray(Array *a, size_t initialSize)
{
    // Allocate initial space
    a->array = (Processes *)calloc(initialSize, sizeof(Processes));

    a->used = 0;                                            // no elements used
    a->size = initialSize;                                  // available nr of elements
}

// Add element to array
void insertArray(Array *a, Processes element)
{

    if (a->used == a->size)
    {
        a->size *= 2;
        a->array = (Processes *)realloc(a->array, a->size * sizeof(Processes));
    }

    a->array[a->used].pid=element.pid;
    a->array[a->used].arrival=element.arrival;
    a->array[a->used].burst=element.burst;
    a->used++;

}

//Functino to free array
void freeArray(Array *a)
{

    free(a->array);
    a->array = NULL;
    a->used = 0;
    a->size = 0;

}

//Function to read from the file
void readFile(char *fileName){

    FILE *fp = NULL;                                               //File pointer
    char *buffer = NULL, *pid = NULL, *arr = NULL, *bur = NULL,*p = NULL;
    Processes temp;
    int count = 0;

    fp = fopen(fileName, "r");
    if(fp == NULL)
        exit(1);

    //Loop to read the file line by line
    while(fgets(buffer, sizeof(buffer), fp)){

/*        copyToken(pid, buffer, sizeof(pid), "\t");
        copyToken(arr, buffer, sizeof(arr), "\t");
        copyToken(bur, buffer, sizeof(bur), "\n");*/

        while (*p) {

            if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {

                // Found a number
                long val = strtol(p, &p, 10); // Read number
                if(count == 0){

                    temp.pid = val;
                    count++;

                }
                else if(count == 1){

                    temp.arrival = val;
                    count++;

                }
                else if(count == 3){

                    temp.burst = val;
                    count++;

                }
            } else {

                p++;
            }
        }

        //Insert element into array
        insertArray(&proc, temp);
        count = 0;

    }
    fclose(fp);

}

/*void copyToken(char * dest, char *source, int len, char const *delim){

    char *token = strtok(source, delim);
    if(token != NULL){

        dest[0] = '\0';
        strncat(dest, token, len-1);

    }

}*/

void fcfs(char *fileName){

    int finCount = 0, sysTime = 0;

    //Calling this function to determine the number of processes
    procNumFunction(fileName);

    //Initializing the array
    initArray(&proc, procNum);
    initArray(&fin, procNum);

    //Reading the file
    readFile(fileName);

    while(finCount <= procNum){

        printf("<system time\t%d> process %d is running\n", sysTime, proc.array[finCount].pid);
        sysTime++;
        if(proc.array[finCount].burst != 0)
            proc.array[finCount].burst--;
        else{

            printf("<system time\t%d> process %d is finished...\n", sysTime, proc.array[finCount].pid);
            finCount++;

        }

    }

    if(finCount > procNum){

        printf("<system time\t%d> All processes finished\n", sysTime);
        printf("==================================================================================\n");

    }

}

void srtf(char * fileName){



}

//The main function of the program
int main(int argc, char *argv[]){

    //Conditions to check if the arguments have been given correctly or not
    if (argc < 2)
        printf("Error. File name missing !!!");
    else if(argc == 2)
        printf("Error. Scheduling type missing !!!");
    else{

        if(!(strcmp(argv[2],"FCFS"))){

            printf("Scheduling algorithm: %s", argv[2]);
            fcfs(argv[1]);                                  //call FCFS

        }
        else if(!(strcmp(argv[2], "RR"))){

            printf("Scheduling algorithm: %s\n", argv[2]);
            if(argc != 4)
                printf("Error. Time quantum not given !!!");
            else{

                //check if valid input

            }

        }
        else if(!(strcmp(argv[2], "SRTF"))){

            printf("Scheduling algorithm: %s", argv[2]);
            srtf(argv[1]);                                  //call SRTF

        }

    }

}

Мой код на этом не завершен точка, но она компилируется и запускается. Я просто хотел запустить программу и посмотреть, правильно ли работает моя программа хотя бы для алгоритма FCFS.

Я протестировал программу, используя этот файл с именем input1.txt

1 0 10
2 0 9
3 3 5
4 7 4
5 10 6
6 10 7

Здесь первое число - это PID для процесса, второе число - время прибытия для процесса и третье число - время взрыва для процесса. Всего существует 6 процессов.

Моя проблема в том, что когда я запускаю программу, она запускается со следующим выводом:

$ ./a.out input1.txt FCFS
Scheduling algorithm: FCFS
Total 5 tasks are read from "input1.txt"

Segmentation fault (core dumped)

Чего я здесь не понимаю в том, что я получаю ошибку сегментации, и после запуска через отладчик eclipse программа останавливается на строке while(fgets(buffer, sizeof(buffer), fp)){ в функции readFile. Может кто-нибудь помочь мне в том, что я делаю неправильно, потому что я считаю, что моя реализация для чтения файла строка за строкой верна?

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 23 марта 2020
  1. Откройте файл в procNumFunction(), но не в fclose(), затем в readFile() попробуйте открыть его снова.

  2. procNum=0; и initArray(&proc, procNum); делает calloc(0, sizeof(Processes))
    Я не уверен, что произойдет при вызове callo c (0), но mallo c (0) здесь не так. (где-то используйте mallo c (0), но здесь это не хорошо)

void * mallo c (размер size_t);

mallo c () выделяет размер байтов и возвращает указатель на выделенную память. Память не очищается. Если размер равен 0 , то mallo c () возвращает либо NULL, либо уникальное значение указателя, которое впоследствии может быть успешно передано free ().

после initArray, a-> used равно 0, a-> size равно 0, затем insertArray()
a->size *= 2;
a->array = (Processes *)realloc(a->array, a->size * sizeof(Processes));

сделать realloc(p, 0) вызов, я думаю, это опасно.

1 голос
/ 23 марта 2020

Ваш buffer - указатель в никуда (места для выделенной строки нет, никогда!). Его размер - это размер указателя (4 или 8 байт), а не место для размещения чего-либо. Сделайте ваш буфер массивом, например, 100 байтов (временное хранилище!), Т.е. char buffer[100].

0 голосов
/ 23 марта 2020

в функции: readFile(), указатель p инициализируется как NULL

Затем выполняется этот оператор:

while (*p) {

И поскольку p содержит NULL, программа обработает sh с событием ошибки сегмента.

...