シンプルなprintfスタイルのロガーを実装しているときに、vsnprintfクラッシュが発生しました。これは、私がロガーユーティリティを呼び出す方法です:シンプルなロガークラスvsnprintfが読み取りアクセス違反でクラッシュする
LoggerUtil->LogInfo("Whatever info here %s", "just a test!");
これは、可変数の引数を持つ関数を呼び出します。アイデアは私fmtを変更する必要があるので、フォーマット文字列に余分な情報を追加することです:主な問題を把握することはできません
std::string LoggerUtil::LogClientInfo(const char* fmt)
{
return "Some info here %s";
}
void LoggerUtil::LogInfo(const char* fmt, ...)
{
std::string formatStr = LogClientInfo(fmt); // returns "Some info here %s" just for testing altering the format string
const char* format = formatStr.c_str(); // checked memory and its '\0' terminated string
va_list arg_list;
va_start(arg_list, format);
Logger::InfoVA(format, arg_list);
va_end(arg_list);
}
void Logger::InfoVA(const char* fmt, va_list arg_list)
{
Log(Priority_Info, fmt, arg_list);
}
void Logger::Log(Priority priority, const char* fmt, va_list args)
{
char str[MaxLogEntrySize];
memset(str,0,MaxLogEntrySize*sizeof(char));
vsnprintf(str,MaxLogEntrySize-1, fmt, args); // CRASH :(
...
}
を、FMTと焼戻しではないことは、問題を解決しますが、それはオプションではありません。
void LoggerUtil::LogInfo(const char* fmt, ...)
{
va_list arg_list;
va_start(arg_list, fmt);
Logger::InfoVA(fmt, arg_list);
va_end(arg_list);
}
私はここで何が欠けていますか?
私はすぐに問題が表示されません。 purifyやvalgrindなどのメモリ計測ツールを使用して、メモリの破損を検索します。ある特定の関数でC++プログラムがクラッシュしたとしても、そのバグはどこにあるのか分かりません。 –
'va_start(arg_list、format);'私はそれが 'va_start(arg_list、fmt);でなければならないと思うあなたは私が得ることができないトリッキーなことをしようとしていない限り。しかし、基本的にあなたは 'va_start'を他の場所でderoutしています。==> UB。私はあなたのコード内のすべての可能性のある問題を修正しているとは確信していないので、これを回答として投稿しませんでした。 –
'C++ 'を使っているので、[可変引数テンプレート](http://en.cppreference.com/w/cpp/language/parameter_pack)を使うなど、可変数の引数を実装する方がはるかに優れています。次に、va_start、va_argなどでこの混乱に陥ることはありません。リンクのサンプルコードを参照してください。 – PaulMcKenzie