具有可变参数崩溃的C函数

时间:2018-04-18 06:44:38

标签: c++ variadic-functions

我编写了一个函数来帮助我调试项目:

    static void outputDebug(unsigned uintLineNo, const char* cpszFormat, ...) {
        char szPrefix[80], szOut[256];
        va_list ap;
        va_start(ap, cpszFormat);
        sprintf_s(szPrefix, sizeof(szPrefix), "%s %s %05ld %s\n"
                          , __DATE__, __TIME__, uintLineNo, cpszFormat);
        vsprintf_s(szOut, sizeof(szOut), "%s", szPrefix, ap);   
        va_end(ap);
        OutputDebugString(szOut);
    }

此功能的一个示例:

    outputDebug(__LINE__, "AdapterInit(%s)", "Test");

格式字符串AdapterInit(%s)之后的所有内容都是可选的,我单独执行该函数并构造szPrefix没有问题,例如这将包含类似的内容; Apr 18 2018 07:33:07 01492 Adapter(%s)

下一行vsprintf会导致异常:

    Unhandled exception at 0x0781e9ee (msvcr90d.dll) in ....

我看不出我做错了什么,怎么解决这个问题?

[编辑]问题出在vsprintf行,删除了不必要的%s解决问题。

工作解决方案:

    static void outputDebug(unsigned uintLineNo, const char* cpszFormat, ...) {
        char szPrefix[80], szOut[256];
        va_list ap;
        va_start(ap, cpszFormat);
        sprintf_s(szPrefix, sizeof(szPrefix), "%s %s %05ld %s\n"
                          , __DATE__, __TIME__, uintLineNo, cpszFormat);
        vsprintf_s(szOut, sizeof(szOut), szPrefix, ap); 
        va_end(ap);
        OutputDebugString(szOut);
    }

1 个答案:

答案 0 :(得分:1)

如果我正确收集,则构造szPrefix作为新格式字符串(通过向其中插入cpszFormat,添加前缀)。因此,对vsprintf_s的调用应使用 ,而不是%s。即。

vsprintf_s(szOut, sizeof(szOut), szPrefix, ap);   

您选择的szPrefix(即80)的大小也相当乐观。可能值得增加一两个等级。