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);
这可以让您在不再需要时明确释放已分配的内存。