Mac上的vsnprintf()给出了EXC_BAD_ACCESS?

时间:2014-04-18 15:46:41

标签: c++ variadic-functions printf

我不确定为什么我在以下代码中看到了EXC_BAD_ACCESS:

template <typename ArgType>
String Format(ArgType args, ...) const {
    va_list argList;
    va_start(argList, args);

    // determine num of chars needed, don't store anything anywhere though!
    size_t charsNeeded = vsnprintf(NULL, 0, ToStdString().c_str(), argList);

    va_end(argList);

    // print formatted string into buf
    va_start(argList, args); // EDIT: new va_list here
    char buf[charsNeeded];
    vsprintf(buf, ToStdString().c_str(), argList);

    va_end(argList);

    return String(buf);
}

编辑:我应该提一下代码应该像这样使用:

String str = String("Hello, %s!").Format("World");

我应该提到String是一个小的包装类,它有一个ToStdString()方法,它返回一个std :: string成员var。

它在vsnprintf()调用中的分段,但我不明白为什么!

1 个答案:

答案 0 :(得分:4)

va_start初始化va_list以在指定的参数之后获取参数,因为在您的示例中,您只向该方法发送一个参数,va_list为空。

您还需要在致电va_list后重新初始化vsnprintf

您需要重新考虑方法的签名,可以执行静态函数:

class String : public std::string {
public:
    String(std::string str) : std::string(str) {}

    String(char *str) : std::string(str) {}

    static String Format(String format, ...) {
        va_list argList;
        va_start(argList, format);

        // determine num of chars needed, don't store anything anywhere though!      
        size_t charsNeeded = vsnprintf(NULL, 0, format.c_str(), argList);

        va_end(argList);
        va_start(argList, format);

        // print formatted string into buf                                           
        char buf[charsNeeded];
        vsprintf(buf, format.c_str(), argList);

        va_end(argList);

        return String(buf);
    }
};

修改

如果您希望格式化字符串,最佳解决方案可能是使用std::stringstreamhttp://www.cplusplus.com/reference/sstream/stringstream/stringstream/