只有2个任务后才有阵列 - 段故障

时间:2018-02-18 03:55:27

标签: c arrays segmentation-fault

这是我的第一篇帖子,所以如果我发布错误的代码格式,我会提前道歉。

我一直试图找出我在这里出错的地方一段时间,但却未能找到答案。在将两行文本文件扫描到我的数组后,我一直遇到分段错误。文本文件遵循以下模式:City1 City2距离。

我觉得它与记忆有关但我无法理解为什么。

#include <stdio.h>
#include <stdlib.h>
#include <string.h> //Chosen to use this library to break text file down.
#include "list.h" //Using file created in lab 3 earlier this year.
#define DYNAMIC_RESIZE 0 ///Might not be needed...
#define Max_Lines 40
#define LINE_SIZE 150

int main()
{
    FILE *Distances_File = fopen("Distances.txt", "r");

    char *City1[Max_Lines];
    char *City2[Max_Lines];
    int *Distances[Max_Lines];

    City1[Max_Lines] = malloc(sizeof(Max_Lines));
    City2[Max_Lines] = malloc(sizeof(Max_Lines));
    Distances[Max_Lines] = malloc(sizeof(Max_Lines));

    char File_Line[LINE_SIZE];
    int Line_Count = 0;

    if (!Distances_File) {
        printf("File could not open");
            return 1;
    }

    if ( Distances_File != NULL )
    {
        ///Intro to the program.
        printf("This is a program that will calculate the shortest distance between selected \ncities.");
        printf("\nSo wish me luck :(\n \n");

        while(fgets(File_Line, sizeof(File_Line), Distances_File))
        {
            //printf("%s", File_Line);
            sscanf(File_Line, "%s%s%s", City1[Line_Count], City2[Line_Count], Distances[Line_Count]);

            ///Still issue of Distances being a char.
            printf("%s\n%s\n%s\n\n", City1[Line_Count], City2[Line_Count], Distances[Line_Count]);

            Line_Count++;
            printf("%d", Line_Count);
        }
    }
}

3 个答案:

答案 0 :(得分:0)

您有访问City1[Max_Lines]的未定义行为,其中数组的大小为Max_Lines。您应该更改它而不是分配内存并使这些指针指向它。所以你会做这样的事情: -

#define MAXLEN 100
...
for(size_y i = 0; i < Max_Lines; i++){
   City1[i] = malloc(MAXLEN);
   /* check malloc return value */
}

此外,您也可以这样做,

char City1[Max_Lines][MAXLEN];

因为在这里如果你想获得MAXLEN字节缓冲区而不是动态分配,你可以这样做。唯一的问题是,如果Max_linesMAXLEN更大,那么可能存在受堆栈大小限制的可能性。然后动态分配将是一次救援。

另外,您应该检查返回值fopen。有些情况fopen失败。您需要单独处理这些案例。

答案 1 :(得分:0)

尝试以下变体:

#include <stdio.h>
#include <stdlib.h>
#include <string.h> //Chosen to use this library to break text file down.
//#include "list.h" //Using file created in lab 3 earlier this year.
#define DYNAMIC_RESIZE 0 ///Might not be needed...
#define Max_Lines 40
#define LINE_SIZE 150

typedef struct {
    char data[LINE_SIZE];
} LineBuffer;

int main()
{
    FILE *Distances_File = fopen("Distances.txt", "r");

    LineBuffer *City1;
    LineBuffer *City2;
    int *Distances;

    char File_Line[LINE_SIZE];
    int Line_Count = 0;

    City1 = (LineBuffer *)malloc(sizeof(LineBuffer)*Max_Lines);
    City2 = (LineBuffer *)malloc(sizeof(LineBuffer)*Max_Lines);
    Distances = (int *)malloc(Max_Lines);

    if (!Distances_File) {
        printf("File could not open");
        return 1;
    }
    if ( Distances_File != NULL ) {
        ///Intro to the program.
        printf("This is a program that will calculate the shortest distance between selected \ncities.");
        printf("\nSo wish me luck :(\n \n");

        while(fgets(File_Line, sizeof(File_Line), Distances_File) && Line_Count < Max_Lines)
        {
            //printf("%s", File_Line);
            sscanf(File_Line, "%s%s%d", City1[Line_Count], City2[Line_Count], Distances[Line_Count]);

            ///Still issue of Distances being a char.
            printf("%s\n%s\n%d\n\n", City1[Line_Count], City2[Line_Count], Distances[Line_Count]);

            Line_Count++;
            printf("%d", Line_Count);
        }
    }

    free(City1);
    free(City2);
    free(Distances);
}

修改

sizeof(int)应为4个字节,因此malloc(sizeof(Max_Lines))将分配4个字节

答案 2 :(得分:0)

本声明

char *City1[Max_Lines];

声明一个char指针数组,数组的大小为Max_Lines

在这里,您将内存分配给数组的无效索引:

City1[Max_Lines] = malloc(sizeof(Max_Lines));

Max_Lines的值为40,因此大小为Max_Lines的数组的有效索引为0-39

在使用数组之前,您需要为数组City1City2的所有指针分配内存。

您可以编写一个函数来执行此分配,如下所示:

void allocate_city_mem(char *arr[], size_t sz) {
        for(size_t i = 0; i < sz; i++)  {
                arr[i] = malloc(LINE_SIZE);
                if (NULL == arr[i])
                        exit(EXIT_FAILURE);
        }
}

这样做完成后,您需要确保free动态分配的内存。你可以这样做:

void free_city_mem(char *arr[], size_t sz) {
        for(size_t i = 0; i < sz; i++) {
                free(arr[i]);
                arr[i] = NULL;
        }
}

在您的计划中,我可以看到Max_LinesLINE_SIZE是较小的值,因此您可以这样做:

char City1[Max_Lines][LINE_SIZE];

有了这个,你就不需要处理任何内存的分配/释放 此外,无需采用整数指针数组来存储距离。 Distances可以是整数数组。

在您的代码中,您在调用fopen()后调用if (!Distances_File) {....并在代码中的下方某处检查它的返回值(malloc)。作为一种良好的编程习惯,在这种情况下你应该立即检查库函数的返回值,因为如果它们失败了,就没有必要继续进行了。
此外,使用scanf族函数时,请确保与传递的参数对应的格式说明符应正确。

以上所有要点,main()都是这样的:

int main() {
    FILE *Distances_File = fopen("Distances.txt", "r");
    if (!Distances_File) {
            printf("File could not open");
            return 1;
    }

    char City1[Max_Lines][LINE_SIZE];
    char City2[Max_Lines][LINE_SIZE];
    int Distances[Max_Lines];
    char File_Line[LINE_SIZE];
    int Line_Count = 0;

    //Intro to the program.
    printf("This is a program that will calculate the shortest distance between selected \ncities.");
    printf("\nSo wish me luck :(\n \n");

    while(fgets(File_Line, sizeof(File_Line), Distances_File)) {
            printf("Line number : %d\n", Line_Count+1);
            //printf("%s", File_Line);
            sscanf(File_Line, "%s%s%d", City1[Line_Count], City2[Line_Count], &Distances[Line_Count]);

            ///Still issue of Distances being a char.
            printf("%s\n%s\n%d\n\n", City1[Line_Count], City2[Line_Count], Distances[Line_Count]);

            Line_Count++;
    }

    return 0;
}