7

snprintf(3) の Linux man ページには、次の例が示されています。

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

char *
make_message(const char *fmt, ...)
{
    int n;
    int size = 100;     /* Guess we need no more than 100 bytes */
    char *p, *np;
    va_list ap;

    if ((p = malloc(size)) == NULL)
        return NULL;

    while (1) {

        /* Try to print in the allocated space */

        va_start(ap, fmt);
        n = vsnprintf(p, size, fmt, ap);
        va_end(ap);

        /* Check error code */

        if (n < 0)
            return NULL;

        /* If that worked, return the string */

        if (n < size)
            return p;

        /* Else try again with more space */

        size = n + 1;       /* Precisely what is needed */

        if ((np = realloc (p, size)) == NULL) {
            free(p);
            return NULL;
        } else {
            p = np;
        }
    }
}

これは/* check error code */すべきではありません:

        if (n < 0) {
            free(p);
            return NULL;
        }

メモリリークを避けるには?

単語とコードの比率が正しくないため、これを投稿できません。そのため、最後にテキストを追加する必要があります。上記は完全で要点なので、この段落は無視してください。これが受け入れられるのに十分なテキストであることを願っています。

ところで:私は最後の行が好きですp = np;

4

2 に答える 2

2

はい、このコードは漏れやすいです。

vsnprintf は、エラー時に負の数を返すことがあります。VC++ では、ターゲット バッファが小さすぎてこのコードのロジックが壊れている場合、vsnprintf は -1 を返します... こちらを参照してください: MSDN VC 実装は C 標準に準拠していません...

vsnprintf エラーのその他の原因は、NULL 'format' バッファの送信、またはフォーマット バッファ内の不正なエンコーディングです。

于 2013-11-21T13:48:56.887 に答える
0

strlenが 内から 0 未満の値を返すかどうかはわかりませんがn = vsnprintf(...)、それが実行された場合 (およびsize > 0)、これは間違いなくメモリ リークを引き起こします。

この関数は、割り当てたメモリを解放せずmake_messageに単純に実行します。元の質問で述べたように、 a がありません。return NULL;p = malloc(size)free(p);

于 2013-11-19T21:31:00.083 に答える