Отладочный макрос, который использует память и освобождает ее? - PullRequest
4 голосов
/ 21 марта 2011

Я написал макрос отладки и хотел бы включить в него время, в этом случае моя функция gettimestr() принимает небольшой буфер (всегда длиной 8, потому что его sprintf дополняет до 00:00:00) и включает это с fprintf внутри. Мой макрос выглядит следующим образом:

#define _DEBUGPRINT(...)    fprintf(stderr, __VA_ARGS__);
#ifndef NDEBUG
#  define WHERESTR  "[[%s] file %s, line %d]: "
#  define WHEREARG  timebufstr_0, __FILE__, __LINE__
#  define DEBUGPRINT(_fmt, ...) \
          char timebufstr_0[8]; \
          gettimestr( timebufstr_0 );\
          _DEBUGPRINT(WHERESTR _fmt, WHEREARG, __VA_ARGS__)
#else
#  define DEBUGPRINT(_fmt, ...)  /**/
#endif

Моей первой попыткой было заставить gettimestr вернуть const char*, но из-за этого трудно освободить память, поэтому я пошел дальше и использовал буфер, если вы можете видеть.

К сожалению, буфер нельзя использовать дважды (два сообщения DEBUGPRINT приведут к ошибке переопределения), а также я считаю, что он не освободит память, потому что он исчезнет при возвращении main, так как его нет в функции?

Мои вопросы:

  • Должен ли я malloc() 8 байтов (или 9, если для \ 0, я не знаю, если это требуется сейчас) вместо [8], чтобы я мог освободить его по требованию в куче?
  • Как я должен быть в состоянии создать буферизовать, уничтожать ссылки и повторно использовать это в другом вызове макроса, чтобы исправить мой проблема, где я не мог назвать это дважды?

Ответы [ 2 ]

3 голосов
/ 21 марта 2011
#define _DEBUGPRINT(...)    fprintf(stderr, __VA_ARGS__);
#ifndef NDEBUG
#  define WHERESTR  "[[%s] file %s, line %d]: "
#  define WHEREARG  timebufstr_0, __FILE__, __LINE__
#  define DEBUGPRINT(_fmt, ...) \
   do { \
      char timebufstr_0[8]; \
      gettimestr( timebufstr_0 );\
      _DEBUGPRINT(WHERESTR _fmt, WHEREARG, __VA_ARGS__) \
   } while (0);
#else
#  define DEBUGPRINT(_fmt, ...)  /**/
#endif

Разрешает многократное использование и освобождает буфер после каждого использования.

0 голосов
/ 21 марта 2011

Вы должны выделить 9 байтов для включения байта '\0'.Лучший способ - сделать это с помощью массива, как указано в вашем коде.Для преодоления проблем двойного определения вы можете заключить его в {}, например:

#define _DEBUGPRINT(...)    fprintf(stderr, __VA_ARGS__);
#ifndef NDEBUG
#  define WHERESTR  "[[%s] file %s, line %d]: "
#  define WHEREARG  timebufstr_0, __FILE__, __LINE__
#  define DEBUGPRINT(_fmt, ...) \
          {\ // <---------
          char timebufstr_0[9]; \
          gettimestr( timebufstr_0 );\
          _DEBUGPRINT(WHERESTR _fmt, WHEREARG, __VA_ARGS__)\
          } // <---------
#else
#  define DEBUGPRINT(_fmt, ...)  /**/
#endif
...