需要帮助解决只在linux中出现的Segmentation Fault

时间:2018-02-11 23:03:05

标签: c linux segmentation-fault

我有一个问题,我的程序 - 在Windows中运行正常 - 在Linux中给我一个分段错误。我已经搜索了许多其他涉及分段错误的问题,我认为它必须对我做一些事情,而不是正确使用malloc

该程序应该采用一个数据文件,该文件被假定为一个列表事件,它具有多个任务,每个任务都有一个相关的完成日期所需的天数。例如,我正在测试的数据文件如下所示:

1          15        3
1          27        6
1          36        4
2          15        5
3          18        4
3          26        1
4          15        2
4          26        7
4          27        7
5          16        4

左列是事件编号,中间列是任务编号,右列是所需的天数。以下是我的代码。

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

int main(int argc, char *argv[])
{
    // Declare variables to be used
    FILE *in;
    FILE *out;
    char* inName;
    char* outName;
    int eventNum, taskNum, daysNum;
    int amtEvents, totalDays = 0;
    int **events;
    int **data, dataSize = 0;
    int currentEvent = 1;

    // Exit program if there are too few arguments entered
    if(argc < 2)
    {
        printf("Too few arguments.");
        return 0;
    }

    // Locate the -input and -output tags to determine
    // file names
    for(int i=0; i<argc; i++)
    {
        if(! strcmp(argv[i], "-input"))
        {
            inName = malloc(strlen(argv[i+1]) * (sizeof(char)));
            strcpy(inName, argv[i+1]);
        }

        if(!strcmp(argv[i], "-output"))
        {
            outName = malloc(strlen(argv[i+1]) * (sizeof(char)));
            strcpy(outName, argv[i+1]);
        }
    }

    if ((in = fopen(inName, "r")) == NULL){
        fprintf(stderr, "Input file usage: %s", inName);
        return 0;
    }


    out = fopen(outName, "w");

    while (!feof(in)) {
        if (fscanf(in, "%d %d %d", &eventNum, &taskNum, &daysNum) != 3)
            break;
        dataSize++;
    }

    in = fopen(inName, "r");

    // Store the data in the file into a
    // dynamically created 2D array
    data = malloc((dataSize) * sizeof(int));
    while (!feof(in)) {
        for(int i=0; i < dataSize+1; i++){
                data[i] = malloc(3 * sizeof(int));

                if (fscanf(in, "%d %d %d", &eventNum, &taskNum, &daysNum) != 3)
                    break;
                data[i][0] = eventNum;
                data[i][1] = taskNum;
                data[i][2] = daysNum;
        }
    }


    // Increment amtEvents for each unique event number
    amtEvents = 1;
    for(int i=0; i<dataSize; i++)
    {
        while(currentEvent != data[i][0])
        {
           amtEvents++;
           currentEvent++;
        }
    }

    // Create another 2D array to store data about
    // each event
    events = malloc(amtEvents * sizeof(int));
    for(int i=0; i < amtEvents+1; i++)
    {

        events[i] = malloc(3 * sizeof(int));
        for(int j=0; j<3; j++){
            events[i][j] = 0;
        }

    }


    for(int i=0; i < dataSize; i++)
    {

        events[data[i][0]-1][1]++;
        if(data[i][2] > events[data[i][0]-1][2])
            events[data[i][0]-1][2] = data[i][2];
    }
    // Header
    fprintf(out, "Project completion timetable\n");
    fprintf(out, "----------------------------------------\n");
    fprintf(out, "Event\tNum of tasks\tMax num.of days\n");
    fprintf(out, "-----\t------\t\t--------\n");


    for(int i=0; i<amtEvents; i++)
    {
        fprintf(out, "%d\t %d\t\t %d\n", i+1, events[i][1], events[i][2]);
        totalDays += events[i][2];
    }

    fprintf(out, "----------------------------------------\n");
    fprintf(out, "Total number of days to finish the project: %d", totalDays);
    free(inName);
    free(outName);
    free(data);
    free(events);
}

我对使用gdb并不是很熟悉,但我通过它运行我的程序,这就是它告诉我的:

Program received signal SIGSEGV, Segmentation fault.
0x0000555555554ead in main ()

好的,谢谢你的帮助。我实施了一些你们建议的改动,现在似乎工作正常。

我认为错误的原因是我在mallocinName使用outName时不记得要考虑空终结符。

1 个答案:

答案 0 :(得分:0)

你遇到了各种各样的问题。我做了一些更正,这段代码似乎对我有用。我刚刚使用valgrind检查来查找您的错误。

一般来说,使用FILE *in = NULL;初始化指针始终是一个很好的策略。

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

int main(int argc, char *argv[])
{
    // Declare variables to be used
    FILE *in = NULL;
    FILE *out = NULL;
    char* inName = NULL;
    char* outName = NULL;
    int eventNum, taskNum, daysNum;
    int amtEvents, totalDays = 0;
    int **events;
    int **data, dataSize = 0;
    int currentEvent = 1;

    // Exit program if there are too few arguments entered
    if(argc < 2)
    {
        printf("Too few arguments.");
        return 0;
    }

    // Locate the -input and -output tags to determine
    // file names
    int i;
    for(i=0; i<argc; i++)
    {
        if(! strcmp(argv[i], "-input"))
        {
            inName = malloc(strlen(argv[i+1]) * (sizeof(char)));
            strcpy(inName, argv[i+1]);
        }

        if(!strcmp(argv[i], "-output"))
        {
            outName = malloc(strlen(argv[i+1]) * (sizeof(char)));
            strcpy(outName, argv[i+1]);
        }
    }

    if ((in = fopen(inName, "r")) == NULL){
        fprintf(stderr, "Input file usage: %s", inName);
        return 0;
    }


    out = fopen(outName, "w");

    while (!feof(in)) {
        if (fscanf(in, "%d %d %d", &eventNum, &taskNum, &daysNum) != 3)
            break;
        dataSize++;
    }

    in = fopen(inName, "r");

    // Store the data in the file into a
    // dynamically created 2D array
    data = malloc((dataSize) * sizeof(int));
    while (!feof(in)) {
        for(i=0; i < dataSize+1; i++){
                data[i] = malloc(3 * sizeof(int));

                if (fscanf(in, "%d %d %d", &eventNum, &taskNum, &daysNum) != 3)
                    break;
                data[i][0] = eventNum;
                data[i][1] = taskNum;
                data[i][2] = daysNum;
        }
    }


    // Increment amtEvents for each unique event number
    amtEvents = 1;
    for(i=0; i<dataSize; i++)
    {
        while(currentEvent != data[i][0])
        {
           amtEvents++;
           currentEvent++;
        }
    }

    // Create another 2D array to store data about
    // each event
    events = malloc(amtEvents * sizeof(int));
    for(i=0; i < amtEvents+1; i++)
    {

        events[i] = malloc(3 * sizeof(int));
        int j;
        for(j=0; j<3; j++){
            events[i][j] = 0;
        }

    }


    for(i=0; i < dataSize; i++)
    {

        events[data[i][0]-1][1]++;
        if(data[i][2] > events[data[i][0]-1][2])
            events[data[i][0]-1][2] = data[i][2];
    }
    // Header
    fprintf(out, "Project completion timetable\n");
    fprintf(out, "----------------------------------------\n");
    fprintf(out, "Event\tNum of tasks\tMax num.of days\n");
    fprintf(out, "-----\t------\t\t--------\n");


    for(i=0; i<amtEvents; i++)
    {
        fprintf(out, "%d\t %d\t\t %d\n", i+1, events[i][1], events[i][2]);
        totalDays += events[i][2];
    }

    fprintf(out, "----------------------------------------\n");
    fprintf(out, "Total number of days to finish the project: %d", totalDays);
    free(inName);
    free(outName);
    free(data);
    free(events);

    return 0;
}

** PS:使用此代码我在Centos7中有一个干净的账单 - Codeblocks - GNU GCC。