Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中sprintf的分段错误_C_Arrays_String_Sockets_Printf - Fatal编程技术网

C语言中sprintf的分段错误

C语言中sprintf的分段错误,c,arrays,string,sockets,printf,C,Arrays,String,Sockets,Printf,此函数位于套接字服务器中。当客户端发送查询时,服务器接受查询并从链接列表中查找匹配项。该函数在最初的几个查询中运行良好,然后出现分段错误。问题发生在sprintf调用时(“在sprintf之前。\n”)后面的调用。我真的不明白为什么它只工作了几次。我做错了什么 char* searchNode(char* query) { int i, isFound, count = 0; node* temp = head; char* searchResult = calloc(1

此函数位于套接字服务器中。当客户端发送查询时,服务器接受查询并从链接列表中查找匹配项。该函数在最初的几个查询中运行良好,然后出现分段错误。问题发生在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";
}
char*searchNode(char*query){
int i,isFound,count=0;
节点*温度=头部;
char*searchResult=calloc(1,sizeof(*searchResult));
char*finalResult=calloc(1,sizeof(*finalResult));;
printf(“搜索节点之前。\n”);
while(临时->下一步){
isFound=TRUE;
温度=温度->下一步;
对于(i=0;i食品名称[i])){
isFound=FALSE;
打破
}
}
如果(isFound==TRUE){/*如果找到匹配项,则将其写入临时字符串*/
printf(“找到匹配项。\n”);
searchResult=realloc(searchResult,strlen(searchResult)+1+strlen(nodeToString(temp))+1);
printf(“在sprintf之前。\n”);
sprintf(searchResult,“%s%s”,searchResult,nodeToString(temp));
count++;/*计算找到的结果数*/
}
}
printf(“最终确定字符串之前。\n”);
如果(计数>0){/*如果至少找到一个结果,则添加并将所有结果与标题行合并*/
sprintf(最终结果,“%d个食物项目被找到。\n\n”,计数);
strcat(最终结果、搜索结果);
免费(搜索结果);
返回最终结果;
}
/*如果未找到匹配项,则返回此消息*/
return“未找到任何食物。\n请检查拼写并重试。\n”;
}

您忘了测试
calloc
是否成功。而且您的使用不正确:您需要为其中以0结尾的字符串分配足够的字节

请注意,
char*searchResult=calloc(1,sizeof(*searchResult))
大错特错:它相当于
/*错误的code*/char*searchResult=calloc(1,1)
而您不能这样做(您需要分配足够宽的字符串);你已经有了一些,但你运气不好,它没有崩溃(因此包含了很多关于UB的答案,请参见示例)

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


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

,写入无效内存并引发未定义的行为。

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

C99和POSIX.1-2001规定,如果调用 到sprintf()、snprintf()、vsprintf()或vsnprintf()将导致复制 在重叠的对象之间发生(例如,如果目标 字符串数组和其中一个提供的输入参数引用同一个数组 缓冲区)


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

只需阅读失败的一行即可

 sprintf(searchResult, "%s%s", searchResult, nodeToString(temp));
它说把搜索结果和其他东西打印到搜索结果中。这不可能奏效


searchResult不是Tardis

您正在尝试将字符串打印到自身中。如果您想将一个字符串附加到另一个字符串,请考虑使用<代码> STARCAT/CODE >或<代码> STRCATA< /COD>。似乎引用了未定义的变量“head”。此类行:char*searchResult=calloc(1,sizeof(*searchResult));不太可能工作,因为(在开始时)searchResult没有指向任何特定的内容,因此如果有任何有用的内容,(当前)int变量isFound设置为TRUE或FALSE,则请求取消引用的大小很可能返回4。但是,它没有初始化为任何一个值,应该在单独的行中定义为bool isFound=FALSE;此行:sprintf(finalResult,“%d个食品项目被找到。\n\n”,计数);将导致未定义的行为,因为它没有指向足够长的区域来包含放置在其中的文本。令人惊讶的是(在不好的意义上)人们如何不知道stdlib函数的安全版本,并且大量偏好其危险的变体…我想说OP只是忘记了(?)要重新定位
finalResult
最终将指向的内容。感谢您的回答。但为什么它能在最初的几个电话中工作,最终崩溃呢?那真让我很烦恼。如果它不对,它就根本不应该起作用。但是为什么呢?这件事我已经坚持了好几天了。我还是不明白。@KolyaH:你错了:UB是不对的,但不幸的是,它有时可能会给人一种工作的感觉。不幸的是,UB并不总是崩溃!(参见我的一些回答中提到的UB)