realloc - утечка памяти - PullRequest
       2

realloc - утечка памяти

1 голос
/ 17 марта 2011

Я получил код 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 ]

1 голос
/ 17 марта 2011

Рассмотрим:

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

0 голосов
/ 22 января 2013

Вы создаете функцию strfree (), и она не используется внутри кода. Память должна быть всегда свободной, если она не используется.

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

Глядя на strfree (), выглядит, что вы тоже где-то зарезервировали память для * s. Сделайте то же самое до завершения кода.

if (!(*s) && !((*s)->buf))
   strfree(&(*s));
0 голосов
/ 18 марта 2011

Как и в случае с 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);
}
0 голосов
/ 17 марта 2011

Если вы написали

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

, это было бы утечкой памяти, потому что если realloc завершится неудачно и вернет NULL, вы потеряете указатель (*s)->buf, который все еще указывает на выделенную память.

Поскольку вы выходите из системы при сбое, это не проблема, но, возможно, ваш статический анализатор игнорирует exit?

...