Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-双重自由或腐败_C_Arrays - Fatal编程技术网

C-双重自由或腐败

C-双重自由或腐败,c,arrays,C,Arrays,代码用途 #include <stdio.h> #include <stdlib.h> #include <string.h> char filename[100]; char *buffer = NULL; int schedtoken; char entries[10]; int fcfs() { int pid[10],at[10],bt[10],st[10],ft[10],tat[10],wt[10],i=0,j=0,processes=6

代码用途

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char filename[100];
char *buffer = NULL;
int schedtoken;
char entries[10];

int fcfs()
{
    int pid[10],at[10],bt[10],st[10],ft[10],tat[10],wt[10],i=0,j=0,processes=6,temp,n1,n2,n3;
    int totwt=0,tottat=0;
    char c1,c2,c3,fcfsselection;

    printf("\n\n\nPlease select the dataset you would like to use\n\n");
    printf(" 1. Dataset1\n 2. Dataset2\n 3. Dataset3\n 4. Quit\n\nSelection:\n");
    scanf(" %c",&fcfsselection);

    // Get data set user wants and amend filename based on selection
    switch(fcfsselection)
    {
        case '1':
            printf("\nYou have selected Dataset1\n");
            strcpy(filename, "datasets/dataset1.txt");
            break;
        case '2':
            printf("\nYou have selected Dataset2\n");
            strcpy(filename, "datasets/dataset2.txt");
            break;
        case '3':
            printf("\nYou have selected Dataset3\n");
            strcpy(filename, "datasets/dataset3.txt");
            break;
        case '4':
            printf("\nThank you for using this tool!");
            break;
        default:
            printf("\nERROR!: Incorrect selection - Returning to Menu\n");
            fcfs();
    }

    //Import dataset file, store the first line of char's (crashes if only checking for ints) and the rest of the ints
    FILE *fp;
    fp=fopen(filename,"r");
    if (fp == NULL) 
    {
        printf("Cannot open file at %s, try again.", filename);
        fcfs();
    }
    else 
    {
        fscanf(fp,"%s%s%s",&c1,&c2,&c3);
        while(fscanf(fp,"%d%d%d",&n1,&n2,&n3)!=EOF)
        {
            pid[i]=n1;
            at[i]=n2;
            bt[i]=n3;
            i++;
        }
    }

    fclose(fp);

    //compare values in arr time to find earliest arrival time. Basically loops through dataset values and sorts them into the arrival order
    for(i=0; i<processes; i++)
    {
        for(j=0; j<processes; j++)
        {
            if(at[i]<at[j]) //if the value of i is smaller than j (basically gets the smallest value in array)
            {
                temp=at[i]; //temp int equals arrival time of i
                at[i]=at[j]; //arrival time i changes to value of arrival time j
                at[j]=temp; //arrival time j becomes original value of arrival time i (basically switching the values of i and j)
                temp=bt[i]; //temp becomes value of burst time i
                bt[i]=bt[j]; //burst time i becomes values of burst time j
                bt[j]=temp; //burst time j becomes the original value of burst time i (basically switching the values of i and j)
                temp=pid[i]; //t changes to value of pid i
                pid[i]=pid[j]; //pid i becomes value of pid j
                pid[j]=temp; //pid j becomes value of t (basically switching the values of i and j)
            }

        }
    }

    //complete calculations
    for(i=0; i<processes; i++)
    {
        if(i==0)
            st[i]=at[i]; //if i equals 0 (basically the beggining of the sim) then the start time equals the arrival time of the first entry (so 0)
        else
            st[i]=ft[i-1]; //otherwise the start value equals the finish value of the last entry run -1

        wt[i]=st[i]-at[i]; //wait time equals the start time of the process minus the arrival time
        ft[i]=st[i]+bt[i]; //finish time equals start time plus run time
        tat[i]=ft[i]-at[i]; // turn around time equals finish time minus arrival time
    }

    tottat=0;

    //print results
    printf("\nPID\t  AT\t BT\t WT\t ST\t TAT\t CT");
    for(i=0; i<processes; i++)
    {
        printf("\n%3d\t%3d\t%3d\t%3d\t%3d\t%3d\t%3d",pid[i],at[i],bt[i],wt[i],st[i],tat[i],ft[i]);
        totwt+=wt[i];
        tottat+=tat[i];
    }
    printf("\n\nAverage Waiting Time:%f",(float)totwt/processes);
    printf("\nAverage Turn Around Time:%f",(float)tottat/processes);

    fclose(fp);

    //Open new file to print output
    FILE *f = fopen("datasets/output.txt", "w");
    if (f == NULL)
    {
        printf("Error opening file!\n");
        exit(1);
    }

    //Print output to file
    fprintf(f, "PID\t  AT\t BT\t WT\t ST\t TAT\t CT");
    for(i=0; i<processes; i++)
    {
        fprintf(f,"\n%3d\t%3d\t%3d\t%3d\t%3d\t%3d\t%3d",pid[i],at[i],bt[i],wt[i],st[i],tat[i],ft[i]);
    }
    fprintf(f,"\n\nAverage Waiting Time:%f",(float)totwt/processes);
    fprintf(f,"\nAverage Turn Around Time:%f",(float)tottat/processes);

    printf("\n\nThe results for the dataset simulated are stored in: datasets/output.txt");

    fclose(f);

    return 0;
}

char* getfile(char *filename)
{
    int string_size, read_size;
    FILE *file = fopen(filename, "r");

    if (file)
    {
        // Seek the last byte of the file
        fseek(file, 0, SEEK_END);
        // Offset from the first to the last byte, or in other words, filesize
        string_size = ftell(file);
        // go back to the start of the file
        rewind(file);

        // Allocate a string that can hold it all
        buffer = (char*) malloc(sizeof(char) * (string_size + 1) );

        // Read it all in one operation
        read_size = fread(buffer, sizeof(char), string_size, file);

        // fread doesn't set it so put a \0 in the last position
        // and buffer is now officially a string
        buffer[string_size] = '\0';

        if (string_size != read_size)
        {
            // Something went wrong, throw away the memory and set
            // the buffer to NULL
            free(buffer);
            buffer = NULL;
        }

        // Always remember to close the file.
        fclose(file);
    }
    // printf("%s",buffer);
    return buffer;
}

void schedintro(int schedtoken)
{
    //take the value of schedtoken, change the value of filename to relavent file path and use getfile to open and then print the file. Call relavent scheduling function to do calculations
    if(schedtoken==1)
    {
        strcpy(filename, "headers/fcfsheader.txt");
        getfile(filename);
        printf("%s",buffer);
        fcfs();
    }
    else if(schedtoken==2)
    {
        strcpy(filename, "headers/sjfheader.txt");
        getfile(filename);
        printf("%s",buffer);
    }
    else if(schedtoken==3)
    {
        strcpy(filename, "headers/rrheader.txt");
        getfile(filename);
        printf("%s",buffer);
    }
}

int schedselect()
{
    //function to display what algorithms can be selected. User input
    // obtained based on these options and user filtered based on switch
    // cases to relevant function path
    char selection;

    // print users options and take their input for switch
    printf("%s",buffer);
    printf("\n\n\nPlease select the Scheduling Algorithm you would like to use\n\n");
    printf(" 1. First Come First Served (FCFS)\n 2. Shortest Job First (SJF)\n 3. Round Robin (RR)\n 4. Quit\n\nSelection:\n");
    scanf("%c",&selection);

    // direct user to specific algorithm function path
    switch(selection)
    {
        case '1':
            //printf("\nYou have selected First Come First Served (FCFS)\n");
            schedintro(schedtoken=1);
            break;
        case '2':
            //printf("\nYou have selected Shortest Job First (SJF)\n");
            schedintro(schedtoken=2);
            break;
        case '3':
            //printf("\nYou have selected Round Robin (RR)\n");
            schedintro(schedtoken=3);
            break;
        case '4':
            printf("\nThank you for using this tool!");
            break;
        default:
            printf("\nERROR!: Incorrect selection - Returning to Menu\n");
            schedselect();
    }
    //printf("%d", schedoption);
    return schedtoken;
}

int main()
{
    strcpy(filename, "headers/introheader.txt");
    getfile(filename);
    schedselect();

    return 0;
}
这段代码应该是用来模拟CPU调度算法的。目前只编写了FCF(先到先得)和SJF(最短作业优先)

问题

运行代码时,我在使用FCFS“路径”时收到以下错误

*** Error in `./test2': double free or corruption (!prev): 0x000055f54ecc7830 ***
从我在网上发现的情况来看,这与内存溢出问题有关,尽管在我的个人电脑上运行,我没有收到路径错误。我已经检查了我的循环和阵列减速,但没有发现问题

我相信我的问题可能与以下循环有关

//compare values in at to find earliest arrival time. Basically loops through dataset values and sorts them into the arrival order
    for(i=0; i<processes; i++)
    {
        for(j=0; j<processes; j++)
        {
            if(at[i]<at[j]) //if the value of i is smaller than j (basically gets the smallest value in array)
            {
                temp=at[i]; //temp int equals arrival time of i
                at[i]=at[j]; //arrival time i changes to value of arrival time j
                at[j]=temp; //arrival time j becomes original value of arrival time i (basically switching the values of i and j)
                temp=bt[i]; //temp becomes value of burst time i
                bt[i]=bt[j]; //burst time i becomes values of burst time j
                bt[j]=temp; //burst time j becomes the original value of burst time i (basically switching the values of i and j)
                temp=pid[i]; //t changes to value of pid i
                pid[i]=pid[j]; //pid i becomes value of pid j
                pid[j]=temp; //pid j becomes value of t (basically switching the values of i and j)
            }

        }
    }
//比较at中的值以查找最早到达时间。基本上,循环遍历数据集值并按到达顺序对它们进行排序
对于fcfs()中的(i=0;i),关闭同一文件两次

fclose(fp)

//打开新文件以打印输出

卸下第二个fclose

如果没有第二个fclose,valgrind将不会为-Dataset3\发出任何信号:

valgrind ./a.out
==22836== Memcheck, a memory error detector
==22836== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==22836== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==22836== Command: ./a.out
==22836== 
(null)


Please select the Scheduling Algorithm you would like to use

 1. First Come First Served (FCFS)
 2. Shortest Job First (SJF)
 3. Round Robin (RR)
 4. Quit

Selection:
1
(null)


Please select the dataset you would like to use

 1. Dataset1
 2. Dataset2
 3. Dataset3
 4. Quit

Selection:
3

You have selected Dataset3

PID   AT     BT  WT  ST  TAT     CT
  3   0  25   0   0  25  25
  1   1   5  24  25  29  30
  2   2  20  28  30  48  50
  0   3   4  47  50  51  54
  4   6  14  48  54  62  68
  5   8   6  60  68  66  74

Average Waiting Time:34.500000
Average Turn Around Time:46.833332

The results for the dataset simulated are stored in: datasets/output.txt==22836== 
==22836== HEAP SUMMARY:
==22836==     in use at exit: 0 bytes in 0 blocks
==22836==   total heap usage: 4 allocs, 4 frees, 2,272 bytes allocated
==22836== 
==22836== All heap blocks were freed -- no leaks are possible
==22836== 
==22836== For counts of detected and suppressed errors, rerun with: -v
==22836== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

除了bruno指出的双重自由问题外,您的代码还有一个超出范围的写错误

char c1,c2,c3,fcfsselection;
...
fscanf(fp,"%s%s%s",&c1,&c2,&c3);  // out-of-bounds write. 

下面是一个报告此错误的工具。

您需要做的第一件事是:删除您拥有的全局变量。然后通过删除代码来简化、缩小范围,直到错误消失。并学习如何使用工具,如.Perfect。这是我的问题!在进一步复制代码后,完全忘记删除较低的条目。非常感谢您hdreserve upvote。更正是使c1、c2和c3字符数组成为字符数组,而不是将%s替换为%c,因为它们绕过了PID等,另一种方法是绕过第一个line@bruno,谢谢你指出了问题的症结所在。我为你出色的教学态度鼓掌。你让人脸红^^^高兴stackoverflowing@bruno,我提出另一个修正,
fscanf(fp,“PID AT BT”)
,它也可以工作吗?可能会毫无危险,我的意思是,如果在文件头中做一些小修改,代码将不起作用,只需3个字,并且必须绕过分隔符/a行。
char c1,c2,c3,fcfsselection;
...
fscanf(fp,"%s%s%s",&c1,&c2,&c3);  // out-of-bounds write.