snprintf手册页面示例有内存泄漏问题吗?

7
Linux中的snprintf(3)手册给出了以下示例:
#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;
        }
    }
}

/* 检查错误代码 */之后,这不应该是:

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

为了避免内存泄漏?请忽略本段内容,因为上面已经完整且简洁地表达了意思。通过添加更多的文本以满足单词和代码比率的要求,我才能发布这条消息。顺便说一句,我喜欢最后一行的代码:p = np;

5
是的。但记住,这个例子是为了展示如何使用snprintf()而不是malloc() - Roddy
2
@Roddy,你说得没错,但是例子不是应该具有典型性吗? - SirDarius
在编程中,不强制要求在同一函数中释放内存。该函数可以返回p,而p可以稍后在主函数中释放。这就是malloc的全部意义,手动控制内存块的可用性。 - H_squared
不错,现在请查看https://www.kernel.org/doc/man-pages/reporting_bugs.html。 - user2404501
我的 printf(3) 有一个不同的示例,模拟了 asprintf 的功能,并使用 snprintf。它的日期是2011年9月28日。 - Fred Foo
显示剩余5条评论
2个回答

2

是的,这段代码有泄漏问题。

vsnprintf在出错时可能返回负数。 在VC++中,当目标缓冲区太小时,vsnprintf返回-1,这会破坏此代码的逻辑... 请参见: MSDN VC实现与C标准不一致...

vsnprintf失败的其他原因包括发送空的'format'缓冲区或格式缓冲区中的编码错误。


0

我不知道在n = vsnprintf(...)中,strlen是否会返回小于零的值,但如果它确实这样做了(并且size > 0),那么这肯定会导致内存泄漏。

make_message函数执行简单的return NULL;,而没有释放使用p = malloc(size)分配的内存。就像你在原始问题中所述的那样,它缺少一个free(p);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接