c string dynamic-allocation

¿Cuál es la forma correcta de escribir una función en C devolviendo una matriz de caracteres?



string dynamic-allocation (5)

Deje que el código de llamada sea responsable de asignar la memoria. Pase el búfer y la longitud del búfer en el ejemplo 2:

bool doSomething(char *s, size_t buflen) { // do something that copies chars to s up to max of buflen return true; }

Esto tiende a reducir las fugas, ya que el código de llamada tiene el control de la administración de la memoria.

Estoy bastante familiarizado con Java, no así en C.

En Java, si tengo un método que hace algo y devuelve una cadena, se vería así:

private String doSomething(...) { String s; // do something; return s; }

El equivalente sintáctico en C no funcionaría y es claramente incorrecto:

char* doSomething(...) { char s[100]; // do something; return s; }

por supuesto que puedo hacer:

char* doSomething(...) { char *s; s = malloc(100 * sizeof(char)); // do something; return s; }

que funcionaría (¡creo!) pero rara vez veo códigos haciendo de esta manera (¿es porque está llenando innecesariamente el montón?)

más comúnmente, veo:

bool doSomething(char *s) { // do something that copies chars to s return true; }

Y las declaraciones de llamada serían:

char s[100]; doSomething(s);

¿Qué pasa si no sé el tamaño de la matriz de caracteres hasta que esté dentro de la función en sí? es decir, no podría declarar la matriz char fuera de la función y luego pasarla.

¿Cuál sería la forma correcta de lidiar con este escenario?


La forma más segura es dejar la responsabilidad de asignar a la persona que llama, según lo dicho por otros.

Pero, si no necesita el código de reentrada y la simplicidad de Java, el equivalente de trabajo sintáctico en C es:

char* doSomething(...) { static char s[100]; // do something; return s; }


No puedes devolver una matriz en C.

Puede devolver un puntero y debe aprender (leyendo un buen libro sobre programación en lenguaje C ) la diferencia entre matrices y punteros.

Un idioma común es devolver un puntero asignado dinámicamente. Entonces deberías tener una convención que diga quién liberará el puntero.

También puede devolver una estructura que contiene una matriz.

addenda

Si quieres tener un recolector de basura en C, prueba el recolector de basura de Boehm


Para cuando no pueda saber el tamaño correcto de la cadena devuelta, use la solución malloc . Por supuesto, tienes que free la cadena, una vez que hayas terminado con ella.


Un ejemplo de caso de asignación estática (está obligado a pensar en el tamaño máximo del búfer en el momento de la compilación)

buf[MAX_NO]; do(buf, MAX_NO); _Bool do(char *s, size_t len) { // use len as boundary in your operations }

o caso de asignación dinámica (usando malloc como usted dijo y usando punteros para guardar la ubicación y el tamaño del búfer)

char *s = NULL; size_t final_len; do(&s, &final_len); _Bool do(char** s, size_t* final_len) { size_t len = discoverSize(); char* buf = (char*) malloc(sizeof(char) * len); *s = buf; //save memory location *final_len = len; //save buffer size // use len as boundary in your operations } // do whatever free(s); //remember to free the buffer for politeness