簡體   English   中英

由於代碼中的未知錯誤導致的分段錯誤

[英]Segmentation fault due to unknown error in code

我是在 AoC 的第一天做的,它要求你把每個小精靈消耗的卡路里加起來,然后你會得到一個包含所需詳細信息的 txt 文件。 我的代碼能夠通過 4 次旋轉來查找精靈卡路里,但由於分段錯誤而在第五次停止,我認為這與 line 變量有關但無法弄清楚。 任何幫助都會得到幫助。

我試圖在使用后釋放變量行的 memory,然后重新分配它,但這似乎沒有什么不同。 它似乎可以很好地進行 4 次嘗試,但我將其輸出為“””

精靈號 0 的卡路里攝入量為 47524

小精靈 1 號卡路里攝入量為 18774

小精靈 2 號卡路里攝入量為 11597

小精靈 3 號卡路里攝入量為 10625

[1] 97205 段錯誤./a.out

"""

我希望 memory 被清除,但似乎並非如此。 有人可以幫助或解釋為什么會發生分段錯誤。

我的代碼如下:

`

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

#define BUFF 500

int array[BUFF];

void read_file(FILE *file, char *line, const size_t lineSize, int counter) {
        int calorie = 0;
        while (strlen(fgets(line, lineSize, file)) != 1) {
                calorie += atoi(line);
        }
        printf("Elf number %d calorie intake was %d\n\n", counter, calorie);
}



int main() {
        int counter = 0;
        int calorie = 0;
        const size_t line_size = 6;
        FILE *fp = fopen("example.txt", "r"); 
        while (counter <= 500) {
                char * line = malloc(line_size);
                read_file(fp, line, line_size, counter);
                counter++;
                free(line);
        }
        return 1;
}

`

前 50 行左右的內容是:

4514
8009
6703
1811
4881
3905
3933
9436
4332

3059
15715
11597
10625
8486

4556
10613
4087
11287
12020
1412

5320
9757
10646
7373
1197
3486
4359

16319
22687
5272

6167
2478
4950
5513
6113
2739
6805
4488
6555
2752

2198
2528
3432
2218
3283
1400
1932
3438
1834
1050
4766
5218
3033
3410

幾個問題...

  1. 當我們到達文件末尾時, fgets返回NULL ,它被傳遞給strlen導致段錯誤
  2. strlen調用用於檢測空行。 一種更簡單的方法是只檢查行中的第一個字符。
  3. main中的循環不會在 EOF 時停止
  4. read_file返回 EOF 標志。
  5. main每次循環迭代時執行malloc/free 循環之前的malloc和循環之后的free更好
  6. main中沒有fclose

這是更正后的代碼。 它用錯誤和修復注釋:

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

#define BUFF 500

int array[BUFF];

#if 0
void
#else
// RETURNS: 0=eof
int
#endif
read_file(FILE * file, char *line, const size_t lineSize, int counter)
{
    int calorie = 0;

// NOTE/BUG: this segfaults in strlen because fgets returns NULL (i.e. this
// means EOF on file)
#if 0
    while (strlen(fgets(line, lineSize, file)) != 1) {
        calorie += atoi(line);
    }
    printf("Elf number %d calorie intake was %d\n\n", counter, calorie);
#else
    // loop until EOF
    int eof = 0;
    while (1) {
        eof = (fgets(line, lineSize, file) == NULL);
        if (eof)
            break;

        // stop on blank line
        if (line[0] == 0)
            break;
        if (line[0] == '\n')
            break;

        calorie += atoi(line);
    }

    printf("Elf number %d calorie intake was %d\n\n", counter, calorie);

    return eof;
#endif
}

int
main()
{
    int counter = 0;
    int calorie = 0;
    const size_t line_size = 6;

    FILE *fp = fopen("example.txt", "r");

// NOTE/BUG: doesn't stop on EOF
// NOTE/BUG: no need to malloc/free on every loop
#if 0
    while (counter <= 500) {
        char *line = malloc(line_size);

        read_file(fp, line, line_size, counter);
        counter++;

        free(line);
    }
#else
    char *line = malloc(line_size);
    while (counter <= 500) {
        if (read_file(fp, line, line_size, counter))
            break;
        counter++;
    }
    free(line);
#endif

#if 1
    fclose(fp);
#endif

    return 1;
}

在上面的代碼中,我使用cpp條件來表示舊代碼與新代碼:

#if 0
// old code
#else
// new code
#endif

#if 1
// new code
#endif

注意:這可以通過unifdef -k運行文件來清理


這是清理后的代碼:

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

#define BUFF 500

int array[BUFF];

// RETURNS: 0=eof
int
read_file(FILE * file, char *line, const size_t lineSize, int counter)
{
    int calorie = 0;

    // loop until EOF
    int eof = 0;
    while (1) {
        eof = (fgets(line, lineSize, file) == NULL);
        if (eof)
            break;

        // stop on blank line
        if (line[0] == 0)
            break;
        if (line[0] == '\n')
            break;

        calorie += atoi(line);
    }

    printf("Elf number %d calorie intake was %d\n\n", counter, calorie);

    return eof;
}

int
main()
{
    int counter = 0;
    int calorie = 0;
    const size_t line_size = 6;

    FILE *fp = fopen("example.txt", "r");

    char *line = malloc(line_size);
    while (counter <= 500) {
        if (read_file(fp, line, line_size, counter))
            break;
        counter++;
    }
    free(line);

    fclose(fp);

    return 1;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM