我得到了一些C代码:
typedef struct {
size_t len;
size_t alloclen;
char *buf;
} str;
void strnappnd(str **s, const char *buf, size_t n) {
if ((*s)->len + n >= (*s)->alloclen) {
size_t nalloclen = (*s)->len + n + 1;
void *tmp = realloc((*s)->buf, nalloclen);
if (!tmp) {
printf("failure");
exit(-1);
}
(*s)->buf = tmp;
(*s)->alloclen = nalloclen;
}
memccpy((*s)->buf + (*s)->len, buf, '\0', n);
(*s)->len += n;
(*s)->buf[(*s)->len] = '\0';
}
void strfree(str **s) {
free((*s)->buf);
free(*s);
*s = NULL;
}
显然,strnappnd在realloc线上泄漏。为什么呢?
答案 0 :(得分:1)
考虑:
void f() {
str *s = (str *)malloc(sizeof(str));
s->len = 5;
s->alloclen = 5;
s->buf = strdup("Hello");
strnappend(&s, " World!", 7);
free(s); /* courtesy of Eric */
}
如果您有类似的内容,realloc()
分配的内存会在f()
剩余时泄漏。
答案 1 :(得分:0)
如果你写了
(*s)->buf = realloc((*s)->buf, nalloclen)
这将是内存泄漏,因为如果realloc
失败并返回NULL
,则会丢失(*s)->buf
指针,该指针仍指向已分配的内存。
由于您在失败时退出,这不是问题,但您的静态分析器可能会忽略exit
?
答案 2 :(得分:0)
像这样的mtrace说“没有内存泄漏”
char *strnappnd(str **s, const char *buf, size_t n) {
...
return (*s)->buf;
}
void strfree(str *s){
free(s->buf);
free(s);
}
使用Frerich提供的示例代码
void f() {
str *s = (str *)malloc(sizeof(str));
s->len = 5;
s->alloclen = 5;
s->buf = strdup("Hello");
s->buf = strnappend(&s, " World!", 7);
strfree(s);
}
答案 3 :(得分:0)
您创建了strfree()函数,但未在代码中使用。 如果不使用,内存总是需要空闲。
if (!tmp) {
printf("failure");
if (!(*s) && !((*s)->buf))
strfree(&(*s));
exit(-1);
}
看起来strfree(),看起来你在某处保留了* s的内存。 在代码完成之前执行相同的操作。
if (!(*s) && !((*s)->buf))
strfree(&(*s));