C语言中sprintf的分段错误
此函数位于套接字服务器中。当客户端发送查询时,服务器接受查询并从链接列表中查找匹配项。该函数在最初的几个查询中运行良好,然后出现分段错误。问题发生在sprintf调用时(“在sprintf之前。\n”)后面的调用。我真的不明白为什么它只工作了几次。我做错了什么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
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)