Sprintf分段错误

numCheck是介于1-1000之间的数字。 只有当我在charcheck中收集sprintf的结果时,此代码才会给我一个段错误。 如果我只是在不使用结果的情况下使用sprintf,我就不会出现seg错误。 这里发生了什么事?

char * numString; int charcheck = sprintf(numString, "%d", numCheck); 

你需要为sprintf提供自己的内存。 另外,不要使用sprintf ,而是使用snprintf

 char buf[1000] = {0}; snprintf(buf, 999, ....); 

或者,您可以动态分配内存:

 char * buf = new char[BUFSIZE]; snprintf(buf, BUFSIZE-1, ...); /* ... */ delete[] buf; 

sprintf的第一个参数必须指向有效的缓冲区。 你有一个char*但它指向垃圾。

将您的代码更改为:

 char numString[80] = { }; int charcheck = sprintf(numString, "%d", numCheck); 

因此numString实际上指向一个有效的缓冲区(在本例中为80个字符,其中所有元素都初始化为0)。

使用snprintf也很好,这样你就可以将缓冲区的大小传递给它,这有助于防止缓冲区溢出:

 const int bufsize = 80; char numString[bufsize] = { }; int charcheck = snprintf(numString, bufsize - 1, "%d", numCheck); 

请注意,从传递给snprintf的缓冲区大小中减去一个,因为您不希望它使用最后一个插槽,您要确保它是NULL以表示字符串的结尾。

作为sprintf的第一个参数给出的指针应该指向sprintf应该写入格式化字符串的内存位置。

在这种情况下,您没有初始化numString以指向为格式化字符串分配的某些内存。 由于numString未初始化,因此可能指向任何位置,并且在您尝试将格式化输出写入该位置时会导致分段错误。

您需要为结果分配空间,例如

 char numString[50]; int charcheck = sprintf(numString, "%d", numCheck); 

在你的情况下,sprintf的内部工作尝试引用NULL,这是你的情况下指针的默认值。

最直接的做法是使用上面的数组,例如,

 char numString[80] = { }; 

塞思,耶稣和克瑞克建议。

我认为……的最后一个答案是一个很好的解释:“sprintf的第一个参数应该指向sprintf应该写入格式化字符串的内存位置。” 因此,除了使用一个字符数组,这将强制为字符串分配内存,您还可以使用:

 char *numstring = (char*) malloc(80); 

这可以让您在不再需要时明确释放已分配的内存。