【问题标题】:Segmentation Fault 11 when trying to create new linked list from sorted list尝试从排序列表创建新链表时出现分段错误 11
【发布时间】:2013-02-01 01:30:13
【问题描述】:

只是为了解释发生了什么,我将一个排序的链表输入到一个方法中。在这个链表中是包含字符串的节点。节点包含字符串,以及后面会提到的 2 个计数器。这些字符串是字母数字的,可以重复。最后,我想输出一个链表,其中每个节点包含一个唯一的单词(全部小写),出现次数的计数器,以及单词不同方差的计数器(方差是由某些字符的不同大小写引起的)。我相信它合乎逻辑;但是,我遇到了分段错误。

提前致谢!

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

typedef int bool;
#define TRUE 1
#define FALSE 0


struct Node{
  char value[100];
  int numOccur;
  int numVariance;
  struct Node *next;
};




struct Node * getFinalNodes(struct Node *head){
    struct Node * curr;
    struct Node * finalNode;
    struct Node * ptr;
    struct Node * finalCurr;
    struct Node * prev;
    int m = 0;
    int z = 0;
    char lowercase1[100];
    char lowercase2[100];

    curr = head;                                        //curr = head of sorted node
    finalNode = head;
    ptr = finalNode;
    finalCurr = finalNode;

    for(m = 0; curr->value[m] != '\0'; m++){
        finalNode->value[m] = tolower(curr->value[m]);          //gets first word all lower-cased
    }

    ptr->numOccur=1;                                     //occurance is 1
    ptr->numVariance=1;                                  //variance is 1
    while(curr != NULL && curr->next != NULL){
        prev = curr;
        curr = curr->next;
        if((strcmp(prev->value, curr->value) != 0) && (strlen(prev->value) == strlen(curr->value))){            //example: Ab vs. AB
            for(z=0; curr->value[z] != '\0'; z++){                                                               //turn prev and curr into lowercase
                lowercase1[z] = tolower(prev->value[z]);                                                        //ex. Ab->ab and AB->ab
                lowercase2[z] = tolower(curr->value[z]);
            }
            if(strcmp(lowercase1,lowercase2) == 0){                                                              //if values are same, that means they are the same words, just different capitalizations
                ptr->numOccur++;
                ptr->numVariance++;
            }
            else{                                                                                               //if values are different, then they are completely different strings and put curr.value into a new finalNode
                strcpy(finalNode->value,lowercase2);
                ptr->next = finalNode;
                ptr = ptr->next;
                ptr->numOccur = 1;
                ptr->numVariance =1;
            }
        }
        else if((strcmp(prev->value, curr->value) != 0) && (strlen(curr->value) != strlen(prev->value))){                                                                     //created arrays for prev and curr
            for(z=0; curr->value[z] != '\0'; z++){                                                               //turn prev and curr into lowercase                                                      //ex. Ab->ab and AB->ab
                lowercase2[z] = tolower(curr->value[z]);
            }
            strcpy(finalNode->value,lowercase2);
            ptr->next = finalNode;
            ptr = ptr->next;
            ptr->numOccur = 1;
            ptr->numVariance =1;
       }
       else if(strcmp(prev->value, curr->value) == 0){
            ptr->numOccur++;
       }
    }
};

【问题讨论】:

  • 将代码放入调试器。它会告诉你 seg-fault 在哪一行。使用调试器检查您的变量,您将了解原因。

标签: c arrays linked-list segmentation-fault nodes


【解决方案1】:

在循环中

while(curr != NULL){
    prev = curr;
    curr = curr->next;
    if((strcmp(prev->value, curr->value) != 0) && (strlen(prev->value) == strlen(curr->value))){

currcurr = curr-&gt;next; 之后是NULL

然后strcmp(prev-&gt;value, curr-&gt;value) 取消引用一个空指针。

您可以将循环条件更改为

while(curr != NULL && curr->next != NULL)

【讨论】:

  • 我改变了它,它摆脱了分段错误!但是,该方法似乎没有输出任何内容...
  • 你在那个函数中没有return,编译器没有抱怨吗?
  • @DanielFischer 编译器不一定会抱怨非空函数未在所有代码路径中返回。这是可能未定义的行为,但实际上可能发生的是调用者将假定堆栈中的值作为返回值。
  • @TheodorosChatzigiannakis 当且仅当使用不存在的返回值时,这是未定义的行为。但是一个好的编译器会在检测到“控制到达非无效函数的结尾”或类似的情况时发出警告。至少如果你要求它警告可疑的构造。
  • @DanielFischer 是的,只有在使用过时才未定义。是的,你是正确的,使用正确的标志,编译器会警告你。但我有点记得 GCC 默认情况下不会警告我。不过,我可能记错了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-20
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
相关资源
最近更新 更多