sprintf_s() 因“调试断言失败”错误而失败
Posted
技术标签:
【中文标题】sprintf_s() 因“调试断言失败”错误而失败【英文标题】:sprintf_s() fails with "debug assertion failed" error 【发布时间】:2016-06-17 15:35:24 【问题描述】:问题可能很简单,但经过数小时的研究和编辑后我无法让它工作,所以我在这里发布我的问题。
我正在尝试制作一个函数,它接收一位整数或两位整数,并在将其转换为两位整数格式(例如 7 到 07)后将其作为字符串返回。
char *to_two_digits(int num)
char num_str[4];
sprintf(num_str, "%d", num);
int length = sizeof(*num_str) / sizeof(char);
static char *return_string;
if (length == 1)
sprintf_s(return_string, "0%d", num);
return return_string;
else if (length == 2)
*return_string = *num_str;
return return_string;
else
printf("Error! Number cannot be represented as a two-digit.");
exit(1);
运行 sprintf_s() 函数时函数失败,错误提示:
--------------- Microsoft Visual C++ 运行时库-----------
调试断言失败!
文件:minkernel\crts\ucrt\src\appcrt\stdio\output.cpp
线路:261
表达式:格式!= nullptr
有什么问题,我该如何解决?提前谢谢你。
【问题讨论】:
你的minimal reproducible example在哪里,我们怎么能看到它?提前谢谢你。 【参考方案1】:您将一个空指针传递给sprintf_s
函数。你在这一行声明的指针
static char *return_string;
从未初始化为指向任何东西。由于它被声明为静态,因此它被预初始化为零(而不仅仅是具有不确定的值)。
这就是消息告诉您的内容。 sprintf_s
代码中有一个 assert
用于检查您是否没有传递空指针,这就是触发的原因。
你应该传入一个指向函数可以写入的缓冲区的指针。但是由于您使用的是 C++,因此您实际上应该为此使用 std::string
,然后您可以从函数中返回它而无需静态变量。
【讨论】:
谢谢你的回答,我会尝试使用字符串类而不是使用静态变量。但是,我是否也知道应该进行哪些编辑才能使用静态变量使代码正常运行? @jake 你需要让指针真正指向某个东西。就像一个适当大小的字符缓冲区。例如:static char return_string[100];
static char return_string[100];
是我之前尝试过的代码之一,并且产生了同样的错误。知道为什么吗?
我没有收到那个错误,@jake。这样对我来说效果很好。 Live demo。我什至在断言处于活动状态的调试版本中对其进行了测试。编译器会自动确定缓冲区的大小,因为它正在调用sprintf_s
的模板版本。该代码还有另一个故障点,编译器警告:返回局部变量地址num_str
。【参考方案2】:
正如它所说的那样——你将一个空指针传递给sprintf_s
。
就是return_string
,你没有初始化它来指向任何东西,更不用说一个足够大的缓冲区来获得实际结果了。它不是不确定的值,而是由于static
而肯定是一个空指针,但这种保证对您没有帮助。
实际上使用static
进行这样的内存管理并不是一个好主意,因为您的函数是 100% 不可重入的。通常你会让你的用户传入一个足够大的缓冲区来获得结果,并让调用范围处理缓冲区的生命周期。
【讨论】:
以上是关于sprintf_s() 因“调试断言失败”错误而失败的主要内容,如果未能解决你的问题,请参考以下文章