我对C比较陌生,正在开发一个程序,用于创建地址信息的链接列表,按字母顺序按城市排序。当我尝试打印列表(只是名称和城市)时,我每次都会遇到一个特定条目的分段错误,大约是列表中的3/4。我使用fgets从文件中逐行读取数据,但我遇到的一个问题是“City State Zip”都是以这种格式排在一行,但我只想打印这个城市。此代码遍历已创建的链接条目列表,并尝试按顺序打印每个条目的名称和城市。我可以浏览并打印名称,但是当我尝试做城市时,其中一个条目就是给出了段错误。由于一些城市是两个单词,我不得不把代码放在那里(这就是为什么我有这四个单词 - 这可能是一个更好的方法,但这就是我的想法)
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()
调用打印导致segfault的特定条目执行四个单词中的每一个时,它看起来像这样:
Tampa_NC_28211
_(null)_
我不明白指针疯狂,所以我一直很困惑,为什么只是这个条目不起作用,我可以做些什么来解决它。我已经尝试在realloc()
之后添加一个if语句来检查fourthWord
是否为NULL
,但它从未输入过static state **symbols;
。有关如何避免segfault的任何帮助吗?
答案 0 :(得分:0)
当strtok()
函数的第一个参数为NULL
并且输入字符串中没有其他标记时,NULL
函数返回NULL
。你没有测试;如果发生这种情况,您只需在其中一个变量中记录NULL
即可。因此,如果您遇到包含少于四个令牌的城市行,您将最终在printf()
个参数中传递至少一个malloc()
。这将产生未定义的行为,并且您观察到的失败可能是实际结果。
更一般地说,如果您确实关心是否发生错误,则应始终检查错误条件的函数返回值,并且通常应该关注是否发生错误。例如,在提供的代码中,除了realloc()
之外,还应检查strtok()
和printf()
的返回值。您还可以查看myCity
的返回值,但在这种情况下,您可能不太关心这些值。
另外,正如@melpomene首次观察到的那样,你分配(然后重新分配)内存,但永远不会释放它。当变量JsonArray jsonArray = jsonObject["Groups"].GetArray();
在循环的每次迭代结束时超出范围时,或者在为其分配新值时更早,您将丢失指向该分配内存的唯一指针。这构成了内存泄漏。但是,泄漏内存通常不会导致分段错误。