私は非常に古い(> 10y)Cコードを現代のLinuxに移植しています。vsnprintf()はどのようにして安全に呼び出しますか?
char* strVPrintf(const String fmt, va_list ap)
{
/* Guess we need no more than 50 bytes. */
int n, size = 50;
char* p = (char*)memMalloc(size), q;
while (1) {
/* Try to print in the allocated space. */
n = vsnprintf(p, size, fmt, ap);
/* If that worked, return the string. */
if (n > -1 && n < size) {
break;
}
/* Else try again with more space. */
if (n > -1) /* glibc 2.1 */
size = n + 1; /* precisely what is needed */
else /* glibc 2.0 */
size *= 2; /* twice the old size */
p = memRealloc(p, size);
}
q = strRegister(p);
memFree(p);
return q;
}
著者は標準vsnprintf()
関数が返すことを想定しているようだ:私はカスタム書かれたvsnprintf()のラッパー内セグメンテーションフォールトを取得しています(どうやらそのタスクが重複して出力文字列やインターンそれらを検出することです)書き込まれた文字数を返し、すべてのargを書式設定するのに十分なスペースがない場合は、単にセンチネル値を返します。つまり、バッファサイズを推測し、必要に応じて増やすことができます。
私のシステム(Ubuntu 14.04、glibc 2.19)では、vnprintfは指定されたスペースに対して引数が多すぎると呼び出されたときにセグメント化エラーを起こします。その間にsnprintf()
ファミリのセマンティクスが大幅に変更されましたか?バッファスペースを十分に確保する現代的な方法は何ですか?
'男vsnprintf':実行私はこれを取得すると
:
ここで何が起こっているかを確認する簡単なテストがあります*関数のsnprintf()とvsnprintf()がありませんsizeバイト以上(終端のヌルバイト( '\ 0')を含む)を書き込みます。この制限のために出力が切り捨てられた場合、戻り値は、十分なスペースが使用可能であった場合に最終文字列に書き込まれる文字数(終了NULLバイトを除く)です。したがって、サイズ以上の戻り値は、出力が切り捨てられたことを意味します。*プログラムのその部分は正しいようです。 – EOF
メモリ割り当ての失敗をチェックしていません。 – user694733
'String'とは何ですか?私はそれが 'char * 'だと思っていますが、その情報も提供するべきです。 –