7

snprintf(3) 的 Linux 手册页给出了以下示例:

#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 The VC implementation doesn't agree with the C standard ...

vsnprintf 失败的其他原因是在格式缓冲区中发送 NULL“格式”缓冲区或错误编码。

于 2013-11-21T13:48:56.887 回答
0

我不知道这strlen会不会从 inside 返回一个小于零的值n = vsnprintf(...),但如果它确实(并且size > 0)这肯定会导致内存泄漏。

make_message函数在return NULL;不释放它分配的内存的情况下执行简单操作p = malloc(size)free(p);就像您在原始问题中所说的那样,它缺少一个。

于 2013-11-19T21:31:00.083 回答