繁体   English   中英

C中sprintf的分段错误

[英]Segmentation fault on sprintf in C

此函数位于套接字服务器中。 当客户端发送查询时,服务器接受查询并从链接列表中查找匹配项。 该函数适用于前几个查询,然后发生分段错误。 问题出现在sprintf调用(“sprintf。\\ n”之前的那个)之后。 我真的不明白为什么它只能工作几次。 我做错了什么?

char* searchNode(char* query) {
    int i, isFound, count = 0;
    node* temp = head;
    char* searchResult = calloc(1, sizeof(* searchResult));
    char* finalResult = calloc(1, sizeof(* finalResult));;

    printf("Before search node.\n");

    while(temp->next) {
        isFound = TRUE;
        temp = temp->next;
        for(i = 0; i < strlen(query); i++) { /* compare each char in both strings */
            if(tolower(query[i]) != tolower(temp->foodName[i])) {
                isFound = FALSE;
                break;
            }
        }
        if(isFound == TRUE) { /* if a match is found, write it into the temp string */
        printf("Match found.\n");
            searchResult = realloc(searchResult, strlen(searchResult) + 1 + strlen(nodeToString(temp)) + 1);
        printf("Before sprintf.\n");
            sprintf(searchResult, "%s%s", searchResult, nodeToString(temp));
            count++; /* count the number of results found */
        }
    }

    printf("Before finalise string.\n");

    if(count > 0) { /* if at least a result is found, add combine all results with a head line*/
        sprintf(finalResult, "%d food item(s) found.\n\n", count);
        strcat(finalResult, searchResult);
        free(searchResult);
        return finalResult;
    }

    /* if no match is found, return this message */
    return "No food item found.\nPlease check your spelling and try again.\n";
}

你忘了测试calloc的成功。 并且您正在错误地使用它:您需要为其中的0终止字符串分配足够的字节。

注意 char* searchResult = calloc(1, sizeof(* searchResult)); 是非常错误的:它相当于/* wrong code*/ char* searchResult= calloc(1,1); 你不能这样做(你需要分配足够宽的字符串); 你有一些未定义的行为 ,你运气不好,它不会崩溃(SO包含很多关于UB 的答案 ,见例如这个 )。

您应该使用snprintf(3) (可能使用strdup(3) )并且您应该考虑终止零字节的snprintf + 1的结果。 如果系统提供,您可能需要使用asprintf(3)

请编译所有警告和调试信息gcc -Wall -Wextra -g 使用valgrindgdb调试器。

我不知道sprintf在将searchResult作为参数传递时会做什么。 我系统上的手册页表明它未定义:

如果调用sprintf(),snprintf(),vsprintf()或vsnprintf()会导致在重叠的对象之间进行复制(例如,如果目标字符串),则C99和POSIX.1-2001指定结果是未定义的数组和一个提供的输入参数引用相同的缓冲区)。

你可能应该在那里使用strcat。

只是读取失败的行

 sprintf(searchResult, "%s%s", searchResult, nodeToString(temp));

它说打印searchResult和其他东西到searchResult。 它不可能工作

searchResult不是Tardis

正在调整searchResult指向的内容,但是finalResult保留指向1个char ,尽管它最终会将所有搜索结果复制到其中,最可能的是更多的1个char ,写入无效内存并引发未定义的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM