c - C 中遍历链表时出现段错误?

标签 c segmentation-fault

我对 C 语言比较陌生,正在开发一个程序,该程序创建地址信息的链接列表,按城市字母顺序排序。当我尝试打印列表(仅显示名称和城市)时,每次都会出现一个特定条目的段错误,大约是列表的 3/4。我使用 fgets 从文件中逐行读取数据,但我遇到的一个问题是“城市州邮政编码”都以这种格式写在一行上,但我只想打印城市。此代码遍历已经创建的条目链接列表,并尝试按顺序打印出每个条目的名称和城市。我可以移动并打印名称,但是当我尝试处理城市时,其中一个条目会出现段错误。由于有些城市是两个词,我必须在其中添加代码(这就是为什么我有这四个词 - 可能有更好的方法,但这就是我想要做的)

void printList() {
    struct addressEntry *current = head;

    while (current != NULL) {
        char *end;

        end = current->firstName + strlen(current->firstName) - 1;
        while (end > current->firstName && isspace(*end)) end--;
        *(end + 1) = 0;

        end = current->lastName + strlen(current->lastName) - 1;
        while (end > current->lastName && isspace(*end)) end--;
        *(end + 1) = 0;

        char * myCity = (char *) malloc(sizeof(char));

        char* firstWord = strtok(current->city," ");
        char* secondWord = strtok(NULL, " ");
        char* thirdWord = strtok(NULL, " ");
        char* fourthWord = strtok(NULL, " ");

        printf("Created four words from white spaces: %s_%s_%s_%s_\n", firstWord, secondWord, thirdWord, fourthWord);

        myCity = (char *) realloc(myCity, 2 + strlen(firstWord) + strlen(secondWord));

        if (strlen(fourthWord) != 5) {
            printf("Made it to one-word city\n");
            myCity = firstWord;
        }
        else {
            printf("Made it to two-word city\n");
            strcpy(myCity, firstWord);
            strcat(myCity, " ");
            strcat(myCity, secondWord);
            printf("Finished two word city: %s\n",myCity);
        }

        current = current->nextEntry;
    }
}

调用realloc()函数后发生段错误。当为导致段错误的特定条目执行 printf() 调用打印四个单词中的每一个时,它看起来像这样:

Tampa_NC_28211
_(null)_

我不太理解指针,所以我一直很困惑为什么只有这个条目不起作用,以及我可以做些什么来解决它。我尝试在 realloc() 之后添加一点 if 语句来检查 fourthWord 是否为 NULL,但它从未输入过。关于如何避免段错误有任何帮助吗?

最佳答案

strtok()函数返回NULL当它的第一个参数是 NULL 时并且输入字符串中不再有标记。你不需要对此进行测试;如果发生这种情况,您只需记录 NULL在你的变量之一中。因此,如果您遇到包含少于四个标记的城市线,您最终将传递至少一个 NULL其中printf()论据。这会产生未定义的行为,并且您观察到的失败可能是实际结果。

更一般地说,如果您实际上关心是否发生了错误,则应该始终检查函数返回值是否有错误条件,并且通常应该关心是否发生了错误。例如,在所提供的代码中,您应该检查 malloc() 的返回值。和realloc() ,除了 strtok() 之外。您还可以检查 printf() 的返回值s,但在这种情况下,您可能不太关心这些。

此外,正如@melpomene 首先观察到的那样,您分配(然后重新分配)内存,但从未释放它。当变量myCity时在循环的每次迭代结束时超出范围,或者在为其分配新值之前超出范围,您将丢失指向已分配内存的唯一指针。这构成了内存泄漏。然而,内存泄漏通常不会导致段错误。

关于c - C 中遍历链表时出现段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32571256/

相关文章:

c++ - 路径如何存储在这种结构中,以及如何将其转换为其他结构?

字符驱动节点未打开

c++ - 比较不同单词在输入 C++ 中出现的次数

c++ - 为什么在创建线程时会出现段错误?

c++ - 是什么导致此代码中的段错误?

c - mallocing 是否等同于具有指定数组大小的指针

c - C 中的宏问题

c - 在 ANSI C 中将 Int 值序列化到 char* 缓冲区

linux - NASM:MOV ECX 上的段错误

c - 为 2D 数组分配内存时出现段错误(核心转储)