1

我有一些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 行泄漏。为什么?

4

4 回答 4

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()

于 2011-03-17T13:02:30.227 回答
0

如果你写

(*s)->buf = realloc((*s)->buf, nalloclen)

那将是内存泄漏,因为如果realloc失败并返回NULL,您将丢失(*s)->buf指针,该指针仍指向已分配的内存。

由于您在失败时退出,这不是问题,但您的静态分析器可能会忽略exit?

于 2011-03-17T13:57:18.610 回答
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);
}
于 2011-03-18T04:26:22.520 回答
0

您创建了 strfree() 函数,并且在代码中不使用它。如果不使用内存,则内存需要始终处于空闲状态。

if (!tmp) {
    printf("failure");
    if (!(*s) && !((*s)->buf))
       strfree(&(*s));
    exit(-1);
}

看着 strfree(),看起来你在某处也为 *s 保留了内存。在你的代码完成之前做同样的事情。

if (!(*s) && !((*s)->buf))
   strfree(&(*s));
于 2013-01-22T16:43:51.120 回答