2013-11-12 4 views
7

страницы в Linux людей для snprintf (3) дают следующий пример:snprintf man страница пример утечка памяти?

#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; 
     } 

для того, чтобы избежать утечек памяти?

Я не могу опубликовать это, потому что отношение слов к коду неверно, поэтому мне нужно добавить еще текст в конце. Пожалуйста, проигнорируйте этот абзац, поскольку приведенное выше является полным и точным. Надеюсь, этого достаточно, чтобы текст был приемлемым.

BTW: Я люблю последнюю линию p = np;

+5

Да. Но помните, что пример призван показать использование 'snprintf()', а не 'malloc()'. – Roddy

+2

@ У вас есть точка, но это не пример, который должен быть ... образцовым? – SirDarius

+0

не обязательно, чтобы память была освобождена в той же функции. Функция может возвращать p и p может быть освобождена позже в основном, например. В этом весь смысл malloc, вручную контролируя доступность части памяти. –

ответ

2

Да, этот код является негерметичным.

vsnprintf может возвращать отрицательное число при ошибке. В VC++ vsnprintf возвращает -1, когда целевой буфер слишком мал, которые расщепляют логика в этом коде ... Смотрите здесь: MSDN Реализация VC не согласен со стандартом C ...

Другие источники для отказа vsnprintf отправляют буфер формата NULL или плохое кодирование в буфере формата.

0

Я не знаю, что когда-нибудь strlen возвращать значение меньше нуля внутри n = vsnprintf(...), но в том случае, когда он сделал (и size > 0), это, безусловно, приведет в утечке памяти.

Функция make_message делает простой return NULL;, не освобождая память, которую она выделила p = malloc(size). Не хватает free(p); так же, как вы заявили в своем исходном вопросе.