Estas devolviendo una dirección de la pila que ya se ha liberado. output, de la función center, es un array y por tanto se dimensiona como variable local perteneciente a dicha función. Cuando la función termina la pila decrece y buffer, que apuntaba al inicio del array, ahora apunta a una dirección de la cual no tienes control.
Si quieres devolver esa cadena debes generarla en el montón (heap) y de esta forma va a persistir. Y sí, si eliminas esa línea del \0, tendrás cosas raras porque strcat busca ese carácter para empezar a copiar la cadena origen.
Igualmente, como has generado la cadena con malloc, debes liberarla con free.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* center(int, char, char *);
int main() {
char* pstr = center(30, '*', "hola");
printf("Value: %s\t Address: %p\n", pstr
, pstr
); }
char* center(int width, char fc, char* str) {
char* buffer
= malloc((width
+1) * sizeof(char)); int cc = 0, n = 0;
n = (width - cc) / 2;
for(int i = 0; i < n; ++i)
buffer[i] = fc;
buffer[n] = '\0';
for(int i
= strlen(buffer
); i
< width
; ++i
) buffer[i] = fc;
buffer[width] = '\0';
return buffer;
}