前段时间,我在linux下编写了一个logger类,并尝试将其移植到Windows(Visual Studio)下,并且它始终崩溃
首先,我必须使用vsprintf的vsprintf_s intead,因为编译器拒绝了它
但我发现的唯一示例似乎无效
“ len”表示错误的值,而不是实际的参数数
这是我调用函数的方式:
Logger::print("Rock and roll");
或
Logger::print("%4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f\n", a.x, a.y, b.x, b.y, c.x, c.y, d.x, d.y);
原始Linux代码:
void Logger::print(const std::string fmt,...)
{
char formatted_string[2*1024];
strcpy(formatted_string,this->prefix);
strcat(formatted_string," ");
char*strPtr=&formatted_string[0]+strlen(this->prefix)+1;
va_list argptr;
va_start(argptr, fmt );
vsprintf(strPtr,fmt.c_str(), argptr);
va_end(argptr);
printf("%s\n",formatted_string);
}
新的Windows代码:
void Logger::print(const std::string fmt, ...)
{
va_list args;
int len;
char * buffer;
va_start(args, fmt);
len = _vscprintf(fmt.c_str(), args); << len contents odd values instead of real number of arguments
va_end(args);
buffer = (char*)malloc(len * sizeof(char));
vsprintf_s(buffer, len, fmt.c_str(), args);
Logger::file << buffer;
free(buffer);
}
致谢
答案 0 :(得分:1)
您正在过早调用va_end
。修正此问题,您也没有计算正确的目标大小,因为_vscprintf
不会 包含vsprintf_s
将使用的终止空字符的空间。>
函数的主体应如下所示,包括删除malloc
调用以使用向量来支持正确的RAII解决方案:
va_list args;
va_start(args, fmt);
int len = _vscprintf(fmt.c_str(), args);
if (len > 0)
{
std::vector<char> buff(len + 1); // include terminator space
vsprintf_s(&buff[0], buff.size(), fmt.c_str(), args);
Logger::file << buff.data();
}
va_end(args);
值得一提的是:在调试器中运行原始代码将导致缓冲区过小,调试器将轻松捕获该异常。调试器是晚餐。
答案 1 :(得分:0)
这是工作代码
void Logger::print(const std::string fmt, ...)
{
va_list args;
int len;
char * buffer;
va_start(args, fmt);
len = _vscprintf(fmt.c_str(), args)+1;
buffer = (char*)malloc(len * sizeof(char));
vsprintf_s(buffer, len, fmt.c_str(), args);
va_end(args);
Logger::file << buffer;
free(buffer);
}