En mis programas en C, a menudo necesito una forma de hacer una representación en cadena de mis ADT. Incluso si no necesito imprimir la cadena en la pantalla de ninguna manera, es bueno tener ese método para la depuración. Entonces, este tipo de función a menudo surge.
char * mytype_to_string( const mytype_t *t );
Realmente me doy cuenta de que tengo (al menos) tres opciones aquí para manejar la memoria para que la cadena regrese.
Alternativa 1: Almacenar la cadena de retorno en una matriz de caracteres estáticos en la función. No necesito pensar mucho, excepto que la cadena se sobrescribe en cada llamada. Lo cual puede ser un problema en algunas ocasiones.
Alternativa 2: Asignar la cadena en el montón con malloc dentro de la función. Realmente ordenado ya que entonces no necesitaré pensar en el tamaño de un búfer o la sobrescritura. Sin embargo, tengo que recordar liberar () la cadena cuando termine, y luego también necesito asignar una variable temporal para que pueda liberar. y luego la asignación del montón es realmente mucho más lenta que la asignación de la pila, por lo tanto, sea un cuello de botella si esto se repite en un bucle.
Alternativa 3: Pase el puntero a un búfer y deje que la persona que llama asigne ese búfer. Me gusta:
char * mytype_to_string( const mytype_t *mt, char *buf, size_t buflen );
Esto trae más esfuerzo a la persona que llama. También noto que esta alternativa me da otra opción en el orden de los argumentos. ¿Qué argumento debería tener primero y último? (en realidad seis posibilidades)
Entonces, ¿cuál debería preferir? ¿Nada porque? ¿Existe algún tipo de estándar no escrito entre los desarrolladores de C?
sysctlbyname
en OS X e iOS