我的程序有问题:我一直在sprintf函数上遇到分段错误而且我无法理解为什么,缓冲区足够大而且我认为正确地传递指针,我就是不能弄清楚为什么它不起作用。
以下是代码:
通话:
char dataBuff[100];
//same error with char *dataBuff=malloc(sizeof(char)*100);
//those vars were declared before
int tmpData[5]={TID,i,JobList[i].Num1,JobList[i].Op,JobList[i].Num2};
//here's the function that return the sigsegv error
BuildCMD(CALC,tmpData,0.f,dataBuff);
BuildCMD代码:
int BuildCMD(enum CMD cmd,int *values,float Res,char *dataBuff)
{
switch(cmd)
{//........
case CALC:
{
//this line cause the error,it's just a formatted parameters list
//note:same error with just
//sprintf(dataBuff,"abc");
spritf(dataBuff,"0*;%d;%d;%d;%d;%d;%d;%.5f|\n",cmd,values[0],values[1],values[2],values[3],values[4],Res);
break;
}
//........
}
}
我很确定问题是“dataBuff”,因为即使我使用sprintf尝试存储一个普通的常量字符串,它也会给我带来同样的错误。 这只是......我无法弄清楚我做错了什么。 提前谢谢。
编辑:问题解决了 作为函数头:int BuildCMD(enum CMD cmd,int *values,float Res,char dataBuff[100])
作为sprintf电话:
sprintf(&dataBuff,"0*;%d;%d;%d;%d;%d;%d;%.5f|\n",cmd,values[0],values[1],values[2],values[3],values[4],Res);
答案 0 :(得分:2)
对于BuildCMD(),参数dataBuff是一个指针。但是你已经将dataBuff声明为指针数组! 如果你有 char dataBuff [100]; 然后你可以使用 BuildCMD(CALC,tmpdata伪,0.f,dataBuff);
答案 1 :(得分:0)
鉴于此功能原型:
int BuildCMD(enum CMD cmd,int *values,float Res,char *dataBuff)
这个电话没有意义:
char *dataBuff[100];
BuildCMD(CALC,tmpData,0.f,dataBuff);
你看到dataBuff的类型是如何错误的?您没有启用编译器诊断吗?你应该,因为编译器会立即捕获到这个错误,而不需要运行它来发现它是错误的。
答案 2 :(得分:0)
尝试取消引用具有无效值的指针时,可能会发生SIGSEV。特别是,对于大多数环境,0是无效值。 printf必须遵循你的值数组,因此可能是你为它分配了一个无效的值。
答案 3 :(得分:0)
你正在分配一个char指针数组而不是一个chars数组,我很确定编译器抱怨在调用BuildCMD时将char **作为char *传递。
无论如何,你应该使用asprintf(我认为,它符合C11标准),因为像这样的固定缓冲区大小会影响未来的程序正确性(你需要增长而你的缓冲区不会,直到遥远的未来某个地方) ,你的程序会爆炸......)。
编辑:正确的版本将是
//Don't do this!
char dataBuff[100];
int tmpData[5]={TID,i,JobList[i].Num1,JobList[i].Op,JobList[i].Num2};
BuildCMD(CALC, tmpData, 0.f, dataBuff);
int BuildCMD(enum CMD cmd, int* values, float Res, char* dataBuff) {
sprintf(dataBuff, "whatever...");
}
这是因为数组标识符被隐式转换为指向它们的第一个元素的指针,因此当传递给BuildCMD时,dataBuff变成char *(这也是sprintf期望作为其第一个参数的类型)。 -----这是正确的,但这不是你应该做的! -----
你应该做的是:
char *data = NULL;
int tmpData[5]={TID,i,JobList[i].Num1,JobList[i].Op,JobList[i].Num2};
BuildCMD(CALC, tmpData, 0.f, &dataBuff);
//do whatever you need to do with the string
free(dataBuff);
//mallocs a buffer in dataBuff, the caller is responsible to free it.
int BuildCMD(enum CMD cmd, int* values, float Res, char** pointerAdress) {
asprintf(pointerAdress, "whatever...");
}
请注意,这会将指针传递给指向BuildCMD的指针(存储在dataBuff中的指针的地址),这样BuildCMD / asprintf就可以在指针指向的内存位置返回一个新分配的指针(在调用之后) ,dataBuff将指向新字符串)。