Много раз, когда я пишу такие функции, они предназначены для форматирования, поэтому центрированная или иначе симпатичная строка не понадобится надолго. Когда это безопасное предположение, я обычно объявляю статический буфер в функции, что-то вроде следующего ...
char *center_or_whatever ( char *instring, int some_param /*,etc*/ ) {
/* --- wrap-around buffer --- */
#define NBUFFS 999
#define BUFFWIDTH 999
static char buffer[NBUFFS][BUFFWIDTH];
static int ibuff = 999999;
char *outstring = NULL;
/* --- assign next buffer to outstring --- */
if ( ++ibuff >= NBUFFS ) ibuff=0;
outstring = buffer[ibuff];
/* --- check to make sure instring and other params won't make
outstring exceed BUFFWIDTH, truncate (or whatever) if necessary, etc --- */
/* --- now do whatever your function's supposed to do --- */
strcpy(outstring,instring); /* just for example */
return ( outstring );
} /* --- end-of-center_or_whatever() --- */
... Так что теперь никому не нужно maloc или освобождать что-либо, пока пользователю не понадобится вывод для более чем вызовов NBUFFS к функции, и пока вывод не понадобится превышают символы BUFFWIDTH. Возможно, это не безопасные предположения, но я часто нахожу что-то вроде NBUFFS = 64 и BUFFWIDTH = 128 более чем достаточно безопасно для того, что я сейчас программирую. И статическое распределение [64] [128] байтов в значительной степени незаметно. Так что большую часть времени для меня простота и безопасность, связанная с тем, чтобы не беспокоиться о malloc / free, вполне стоит дополнительных нескольких байтов и нескольких строк кода.
Обратите внимание, что вы также можете объявить один большой, длинный статический буфер символов [99999]; и поддерживать указатель, который инициализирован статический символ * buffptr = buffer . Затем во время каждого вызова присваивайте outstring текущему buffptr , bump buffptr и оберните его, когда он переполнится. Это немного более гибко и требует несколько (но не много) дополнительных строк кода.