C中seg故障的原因

C中seg故障的原因,c,memory,C,Memory,在我的程序中,我遇到seg故障,我不确定原因或如何找出原因。任何帮助都将不胜感激 在代码中,我试图逐字阅读,但我需要跟踪行号。然后我尝试创建一个链表,其中的数据是单词和行号 (有两个文件一起编译) 如果您手头没有一个好的调试器,那么一个好的退路就是在代码的各个步骤中添加几个printf语句,这样您就可以看到它在崩溃之前能走多远 在此代码中: char **str[wCount+1];/*where the lines are being stored*/ int j=0; while(!feof

在我的程序中,我遇到seg故障,我不确定原因或如何找出原因。任何帮助都将不胜感激

在代码中,我试图逐字阅读,但我需要跟踪行号。然后我尝试创建一个链表,其中的数据是单词和行号

(有两个文件一起编译)


如果您手头没有一个好的调试器,那么一个好的退路就是在代码的各个步骤中添加几个
printf
语句,这样您就可以看到它在崩溃之前能走多远

在此代码中:

char **str[wCount+1];/*where the lines are being stored*/
int j=0;
while(!feof(file)){/*inserting lines*/
   fscanf(file, "%s", &str[j]);
   j++;
}
str
是指向
char*
s的指针数组。在循环中,您正在将每一条输入读入其中的一个插槽中。有几个问题

  • 我认为
    *
    s与
    &
    s的数量有误(我通常不会使用那么多级别的指针间接寻址来编程,以避免对它们进行太多的思考;-)
    &str[j]
    是该数组元素的地址,但该数组元素是指向指针的指针;现在您有了指向指针的指针。如果您改为使用
    char*str[wCount+1]
    ,并读入
    str[j]
    ,我认为它可能匹配。(我也不怎么使用
    fscanf
    ,所以也许有人可以确定如何最好地使用它。)

  • 更明显的是,实际上并没有为字符串数据分配任何内存。您只为阵列本身分配它。您可能希望为每个调用分配一个固定的数量(您可以在每次
    fscanf
    调用之前在循环中这样做)。请记住,您的
    fscanf
    实际上可能会读取超过该固定大小的内容,从而导致另一个内存错误。同样,解决这一问题需要一位
    fscanf
    使用方面的专家


  • 希望这有助于开始。如果
    printf
    建议在代码中找到一个更具体的失败点,请将其添加到问题中。

    如果您手头没有一个好的调试器,一个好的回退方法是在代码中的各个步骤中简单地添加几个
    printf
    语句,这样您就可以看到它在崩溃之前能走多远

    在此代码中:

    char **str[wCount+1];/*where the lines are being stored*/
    int j=0;
    while(!feof(file)){/*inserting lines*/
       fscanf(file, "%s", &str[j]);
       j++;
    }
    
    str
    是指向
    char*
    s的指针数组。在循环中,您正在将每一条输入读入其中的一个插槽中。有几个问题

  • 我认为
    *
    s与
    &
    s的数量有误(我通常不会使用那么多级别的指针间接寻址来编程,以避免对它们进行太多的思考;-)
    &str[j]
    是该数组元素的地址,但该数组元素是指向指针的指针;现在您有了指向指针的指针。如果您改为使用
    char*str[wCount+1]
    ,并读入
    str[j]
    ,我认为它可能匹配。(我也不怎么使用
    fscanf
    ,所以也许有人可以确定如何最好地使用它。)

  • 更明显的是,实际上并没有为字符串数据分配任何内存。您只为阵列本身分配它。您可能希望为每个调用分配一个固定的数量(您可以在每次
    fscanf
    调用之前在循环中这样做)。请记住,您的
    fscanf
    实际上可能会读取超过该固定大小的内容,从而导致另一个内存错误。同样,解决这一问题需要一位
    fscanf
    使用方面的专家


  • 希望这有助于开始。如果
    printf
    建议在代码中找到一个更具体的失败点,则将其添加到问题中。

    此代码的问题率相当高。我将仅剖析前几行,给出一个想法:

    void main(整型argc,字符**argv){

    main
    应该返回
    int
    ,而不是
    void
    。可能不会引起您的问题,但也不正确

    file = fopen(argv[1],"r");
    
    在尝试使用
    argv[1]
    之前,您确实需要检查
    argc
    的值。在没有参数的情况下调用程序可能会导致问题。这可能是问题的原因,具体取决于您调用程序的方式

    struct fileIndex *fIndex = NULL;
    
    除非您包含了一些未显示的标题,否则不应该编译--
    struct fileIndex
    似乎没有定义(在您发布的代码中,我看到的任何地方似乎也没有定义)

    这(
    wordcount
    )读取到文件的末尾,但之后不会倒带文件

    char **str[wCount+1];/*where the lines are being stored*/
    
    根据您的描述,您实际上根本不需要存储行(复数)。您可能想要的是读取一行,然后将其标记化并插入单个标记(以及行号)在你的索引中,然后阅读下一行。然而,根据你所说的,没有真正的理由一次存储多个原始行

    int j=0;
    while(!feof(file)){/*inserting lines*/
    
    如上所述,您之前已经读取到文件的末尾,并且从未重绕过文件。因此,此循环中的任何内容都不应执行,因为一旦到达此处,
    feof(file)
    应返回
    true
    。当/如果您注意到这一点,此循环将无法正常工作——事实上,此循环的形式为
    while(!feof(file))
    基本上总是错误的。在这种情况下,您需要检查
    fscanf
    的结果,如下所示:

    while (1 == fscanf(file, "%1023s", line))
    
    …因此,在尝试读取失败时退出循环

        fscanf(file, "%s", &str[j]);
    
    这里的内容基本上等同于臭名昭著的
    get
    ——您没有做任何事情来限制输入到缓冲区的大小。如上所示,您通常希望使用
    %[some_number]s
    ,其中
    some_number
    比您正在使用的缓冲区的大小小一个(当然,要做到这一点,您确实需要一个缓冲区,而您也没有缓冲区)

    您也没有将行数限制为已分配的空间量(但是,与单独的行一样,您没有分配任何空间)。我几乎不愿意这样做
        fscanf(file, "%s", &str[j]);