Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: reconFito en 4 Abril 2022, 22:15 pm



Título: [C] [solved] Comportamiento inesperado
Publicado por: reconFito en 4 Abril 2022, 22:15 pm
Hola a todos.
Estoy tratando de implementar el metodo str.center() que existe en Python pero en C y de paso estoy
aprendiendo a programar en C, pero al borrar la linea que añade el carácter nulo al String resultante obtengo un resultado indeseado.

He estado dandole vueltas al asunto pero no me da el maní que tengo por cerebro, asi que acudo a ustedes en buscas de respuesta.

Muchas Gracias.


Código
  1. #include <stdio.h>
  2. #include <string.h>
  3. char* center(int, char, char *);
  4. int main()
  5. {
  6.    char* pstr = center(30, '*', "hola");
  7.    printf("Value: %s\t Address: %p\n", pstr, pstr);
  8.    return 0;
  9. }
  10.  
  11. char* center(int width, char fc, char* str) {
  12.    char output[width];
  13.    char* buffer = NULL;
  14.    int   cc = 0, n = 0;
  15.    for(char* i = str; *i != '\0'; ++i) cc += 1;
  16.    n = (width - cc) / 2;
  17.    for(int j = 0; j < n; ++j) output[j] = fc;
  18.    output[n] = '\0'; // Al borrar esta linea obtengo una salida incorrecta
  19.    strncat(output, str, cc);
  20.    for(int i = strlen(output); i < width; ++i) output[i] = fc;
  21.    return (buffer = output);
  22. }
  23.  


Título: Re: [C] [unsolved] Comportamiento inesperado
Publicado por: MAFUS en 5 Abril 2022, 00:05 am
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.

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. char* center(int, char, char *);
  6.  
  7. int main() {
  8.    char* pstr = center(30, '*', "hola");
  9.    printf("Value: %s\t Address: %p\n", pstr, pstr);
  10.    free(pstr);
  11. }
  12.  
  13. char* center(int width, char fc, char* str) {
  14.    char* buffer = malloc((width+1) * sizeof(char));
  15.    int   cc = 0, n = 0;
  16.  
  17.    cc = strlen(str);
  18.    n = (width - cc) / 2;
  19.  
  20.    for(int i = 0; i < n; ++i)
  21.        buffer[i] = fc;
  22.    buffer[n] = '\0';
  23.  
  24.    strncat(buffer, str, cc);
  25.  
  26.    for(int i = strlen(buffer); i < width; ++i)
  27.        buffer[i] = fc;
  28.    buffer[width] = '\0';
  29.  
  30.    return buffer;
  31. }


Título: Re: [C] [unsolved] Comportamiento inesperado
Publicado por: reconFito en 5 Abril 2022, 00:33 am
@Mafus, gracias por tu respuesta, el problema no es con el valor de retorno, pero
leyendo un poco tu respuesta sobre como strncat funciona, ahora comprendo que mi
problema estaba en la concatenación y en el no entender bien como funciona strncat.

Gracias @Mafus.


Título: Re: [C] [solved] Comportamiento inesperado
Publicado por: MAFUS en 6 Abril 2022, 10:50 am
Ok, pero sí, también tenías ese problema con el retorno, aunque aparentemente te funcionara el programa.