2012-05-13 10 views
0

私のC++ WinAPIアプリケーションでC文字列とstd::stringを少し簡単に組み合わせる機能を作ろうとしています。std :: stringsとC-Stringsを組み合わせるとバッファオーバーランが発生する

ので、代わりにこれを行う:

TCHAR res[MAX_PATH]; 
_stprintf(res, _T("In functionX(): error occured where the variable values are %d, %u, %s, %c"), myInt, myUnsignedInt, myStr.c_str(), myChar); 
MessageBox(NULL, res, _T("Error Occurred"), MB_OK); 

私は(私はどこでもTCHARの配列を宣言維持する必要はありませんので、それは少し楽異なる文字列型をマージすることができた)これを実行する必要があります:

tstring res = concat(_T("In functionX(): error occured with the variable values %d, %u, %s, %c"), myInt, myUnsignedInt, myStr.c_str(), myChar); 
MessageBox(NULL, (LPTSTR)res.c_str(), _T("Error Occurred"), MB_OK); 

私の問題: My機能CONCAT();パラメータの中に2つ以上の変数を渡すとが失敗し、なぜその理由がわからないのですか?私は、Microsoft Visual C++用の関数を実行するときに発生する

// The following function call causes the error 
tstring ou = concat(_T("In functionX(): Failed to create temp file - %s - %s\r\n"), (LPTSTR)tempFileRootDir.c_str(), tempFile); 

tstring WinFile::concat(TCHAR* strFormat, TCHAR* format, ...) 
{ 
    // tstring is either a std::string or std::wstring depending on whether unicode is used 
    // Post: Wrapper function to easily merge C++ strings with C Strings 

    va_list arguments; 
    va_start(arguments, format); 
    TCHAR res[MAX_PATH]; 
    _stprintf(res, strFormat, format); 
    return tstring(res); 
} 

エラーは次のとおりです。

バッファオーバーランが は、プログラムの内部状態が破損していたApplication.exeで発生しています。ブレークを押して プログラムをデバッグするか、プログラムの終了を続行します。

詳細については、「バッファオーバーランをデバッグする方法 問題」を参照してください。

+1

なぜMAX_PATH文字を持つと宣言していますか?パスをコピーしていません。あなたは、MAX_PATH以上の文字を書くことを試みていると思います。 –

+0

オプションとして、ATL :: CStringを使用できます。 Formatメソッドを持っています。 –

+1

'STD'を大文字にする理由は何ですか?それは普通、性感染症を意味するのですか?小文字のC++標準ライブラリの名前空間は 'std'です。 – jalf

答えて

1

varargsの処理が少しずれているようです。そして、固定サイズのバッファに書き込むことで、スタックのオーバーフローを要求しています。

最初のものを修正するには、printfのvarargs-accepting版を使用する必要があります。 2番目の場合は、印刷する前に数えてください:

tstring WinFile::concat(TCHAR const * strFormat, ...) 
{ 
    va_list args; 

    // Determine how much space to reserve. 
    va_start(args, strFormat); 
    size_t msg_len=_vsctprintf(strFormat, args); 
    va_end(args); 

    // Reserve space on heap. 
    // 
    // "_vscprintf returns the number of characters that would be generated 
    // if the string pointed to by the list of arguments was printed ... 
    // [and] does not include the terminating null character." 
    // 
    // So we add space for a terminating null. 
    std::vector<TCHAR> writebuffer(1+msg_len); 

    // perform formatting 
    va_start(args, strFormat); 
    _vstprintf(&writebuffer[0], strFormat, args); 
    va_end(args); 

    // return a copy as a tstring. 
    return tstring(&writebuffer[0], &writebuffer[msg_len]); 
} 
+1

私は 'concat'という名前は少し誤解を招くと思います。おそらく 'WinFile :: format_msg'ですか? – Managu

+0

教えてくれてありがとう。私はwritebufferを宣言するエラーを受け取ります: "式は定数値を持たなければなりません"。ベクターを宣言するか、代わりにtstringを使用する私の唯一の解決策ですか? –

+0

ダイナミックなサイズの配列は標準C++ではありませんか?たぶん 'std :: vector'を使うのが最も良いでしょう。特に、cスタイルの関数( '_vstprintf')を使って' tstring'に直接書き込もうとすると、ほぼ間違いです。私はそれに応じて私の答えを変更しました。 – Managu

関連する問題