【问题标题】:How can I solve this segmentation fault in linear search with C?如何使用 C 解决线性搜索中的这种分段错误?
【发布时间】:2022-10-06 17:39:48
【问题描述】:

我必须使用学生列表文件进行线性搜索。

该文件按年份排序。我必须从文件中接收年份、学生姓名。如果名称相同,我必须将频率添加到freq[]。如果是不同的名字,可以在数组末尾添加一个学生姓名结构。当我在 Ubuntu 中运行 gdb 时,我可以编译它,但是当我添加频率时,我不断收到错误。


In particular, this part produces a segmentation fault. If I annotated this line, there is no segmentation fault, but the execution does not stop. 
Structure is here.

请帮我

  • Step 1. 检查第一个fscanf(fp, \"%d %s %c %d %*c\", &year, buff.name, &(buff.sex), &count)的返回值,看是否为4。 2) 添加宽度限制%s --> %19s 3) if(rs == EOF) break; --> if(rs != 4 EOF) break;
  • 同时显示minimal reproducible example。并考虑投入大约一个小时来学习调试器的基础知识,这是查找此类错误的完美工具。
  • me_river,代码未显示在过去之前如何分配names。发布minimal reproducible example/
  • 我猜names->data 有空间容纳names->capacity tNames。当names->len 超过names->capacity-1 时,你需要realloc 吗?
  • 我的意思是你确实打电话给realloc,但当时容量可能已经超出了。

标签: arrays c sorting segmentation-fault linear-search


【解决方案1】:

您的功能存在多个问题:

  • 你不测试fscanf() 的返回值。转换失败不会被检测到,您甚至可能在跳过初始记录时出现无限循环。

  • 您应该检查 realloc 是否无法重新分配数组。

  • 使用" %s" 读取buff.name 是有风险的:您应该使用" %19s" 指定要存储到目标数组中的最大字符数,但请注意这种转换不允许多个名称。

  • 最后一次转换" %*c" 很奇怪:你打算这样跳过换行符吗?它不起作用,因为空间已经消耗了它,而您将消耗下一行的第一个字符。您不应该使用fscanf(),而是使用fgets() 来读取整行并使用sscanf() 来解析它。

  • 目前尚不清楚count 变量的用途是什么。

  • freq 是什么意思经常光顾或者频率?

这是一个简化版本:

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

#define MAX_YEAR_DURATION 10

typedef struct {
    char name[20];
    char sex;
    int freq[MAX_YEAR_DURATION];
} tName;

typedef struct {
    int len;
    int capacity;
    tName *data;
} tNames;

int load_names_lsearch(FILE *fp, int start_year, tNames *names) {
    char buf[200];
    tName buff;
    int num = 0;    /* number of records added */
    int year, i, count, year_duration;

    while (fgets(buf, sizeof buf, fp)) {
        if (fscanf(fp, "%d %19s %c %d", &year, buff.name, &buff.sex, &count) != 4) {
            fprintf(stderr, "invalid record: %s", buf);
            continue;
        }
        if (year < start_year || year >= start_year + MAX_YEAR_DURATION) {
            /* ignore record */
            continue;
        }
        year_duration = year - start_year;

        /* try and locate same student and update freq */
        for (i = 0; i < names->len; i++) {
            if (strcmp(names->data[i].name, buff.name) == 0 && names->data[i].sex == buff.sex) {
                names->data[i].freq[year_duration] += 1;
                break;
            }
        }

        if (i == names->len) {
            /* student was not found: add new record */
            /* check for available space */
            if (names->len >= names->capacity) {
                int new_capacity = names->len + 1000;
                tName *new_data = realloc(names->data, new_capacity * sizeof(*names->data));
                if (new_data == NULL) {
                    fprintf(stderr, "cannot reallocate data for %d capacity\n", new_capacity);
                    return -1;
                }
                names->capacity = new_capacity;
                names->data = new_data;
            }
            /* append new record */
            memset(buff.freq, 0, sizeof buff.freq);
            buff.freq[year_duration] = 1;
            names->data[names->len++] = buff;
            num++;
        }
    }
    return num;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多