numCheck是1-1000之间的数字。只有当我在charcheck中收集sprintf的结果时,此代码才会给我一个段错误。如果我只是在不使用结果的情况下使用sprintf,我就不会遇到seg错误。这里发生了什么?
char * numString;
int charcheck = sprintf(numString, "%d", numCheck);
答案 0 :(得分:8)
您需要为sprintf
提供自己的记忆。另外,请勿使用sprintf
,而应使用snprintf
:
char buf[1000] = {0};
snprintf(buf, 999, ....);
或者,您可以动态分配内存:
char * buf = new char[BUFSIZE];
snprintf(buf, BUFSIZE-1, ...);
/* ... */
delete[] buf;
答案 1 :(得分:1)
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
表示字符串的结尾。
答案 2 :(得分:1)
作为sprintf
的第一个参数给出的指针应指向sprintf
应写入格式化字符串的内存位置。
在这种情况下,您没有初始化numString
以指向为格式化字符串分配的内存。由于numString
未初始化,因此可能指向任何位置,并且在您尝试将格式化输出写入该位置时会导致分段错误。
答案 3 :(得分:0)
您需要为结果分配空间,例如
char numString[50];
int charcheck = sprintf(numString, "%d", numCheck);
在你的情况下,sprintf的内部工作尝试引用NULL,这是你案例中指针的默认值。
答案 4 :(得分:0)
最直接的做法是使用上面的数组,例如
char numString[80] = { };
塞特,耶稣和克瑞克建议。
我认为......的最后一个答案是一个很好的解释:“sprintf的第一个参数应该指向sprintf应该写入格式化字符串的内存位置。”因此,除了使用一个字符数组,这会强制为字符串分配内存,你也可以使用它:
char *numstring = (char*) malloc(80);
这可以让你在不再需要时明确释放分配的内存。