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;
答案 0 :(得分:2)
是的,这段代码是漏洞。
vsnprintf可以在出错时返回负数。 在VC ++中,当目标缓冲区太小而破坏了此代码中的逻辑时,vsnprintf返回-1 ... 看这里: MSDN VC实施不符合C标准......
vsnprintf失败的其他来源是在格式缓冲区中发送NULL'格式'缓冲区或错误编码。
答案 1 :(得分:0)
我不知道strlen
会在n = vsnprintf(...)
内返回小于零的值,但如果它(&size > 0
)这样做肯定会导致内存泄漏。
make_message
函数执行简单return NULL;
而不释放它使用p = malloc(size)
分配的内存。正如您在原始问题中所述,它遗漏了free(p);
。