es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Utilizar realloc para escribir en una nueva cadena de texto?

La función remove_multiple toma un parámetro (una cadena C) y elimina los duplicados. Debe devolver la cadena asignada dinámicamente en el montón (heap).

He intentado:
– crear un nuevo puntero asignado dinámicamente (s);
– si el carácter actual (de str) no es igual al siguiente carácter, simplemente copiarlo en s, después de haber realocado (s).

El problema es que todavía tengo esta advertencia en realloc: “C6308 ‘realloc’ podría devolver un puntero nulo: asignar un puntero nulo a ‘s’, que se pasa como argumento a ‘realloc’, hará que el bloque de memoria original se pierda”, y cuando intento depurar el programa obtengo un mensaje que dice que estaba intentando escribir fuera de la memoria asignada.

Aquí está mi código:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char* remove_duplicates(const char* str) {
    char* s = malloc(sizeof(char));
    if (!s) {
        return NULL;
    }
    for (size_t i = 0; str[i] != 0; i++) {


        if (str[i] != str[i + 1]) {
            s = realloc(s, 2 * sizeof(char));
            if (!s) {
                return NULL;
            }
            s[i] = str[i];
        }
    }

    return s;
}



int main(void) {
    char str[] = "heyyyy";
    char* s = remove_duplicates(str);
    printf("%s", s);

    free(s);
    return 0;
}

Listado de errores:
– Advertencia C6308 ‘realloc’ podría devolver un puntero nulo: asignar un puntero nulo a ‘s’, que se pasa como argumento a ‘realloc’, hará que el bloque de memoria original se pierda.</stdio.h></string.h></stdlib.h>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema con tu código es que estás reasignando la memoria para la nueva cadena en cada iteración del bucle, en lugar de asignar la memoria para la longitud final de la cadena solo una vez. Además, no estás indexando correctamente la nueva cadena en tu bucle.

    Aquí tienes una versión corregida del código:

    char* remove_duplicates(const char* str) {
        size_t len = strlen(str);
        char* s = malloc(len + 1);
        if (!s) {
            return NULL;
        }
        size_t j = 0;
        for (size_t i = 0; i < len; i++) {
            if (str[i] != str[i + 1]) {
                s[j++] = str[i];
            }
        }
        s[j] = '\0';
        s = realloc(s, j + 1);
        if (!s) {
            return NULL;
        }
        return s;
    }
    

    En esta versión, primero calculamos la longitud de la cadena de entrada, luego asignamos memoria para la nueva cadena con la misma longitud más uno (para el carácter de terminación nulo). Luego recorremos la cadena de entrada, copiando caracteres en la nueva cadena solo si no son iguales al siguiente carácter. Nos aseguramos de indexar la nueva cadena con j, que se incrementa solo cuando se agrega un nuevo carácter. Después del bucle, agregamos el carácter de terminación nulo a la nueva cadena y luego reasignamos la memoria a la longitud final (que es j + 1, ya que j es el índice del último carácter). Por último, devolvemos la nueva cadena.

    Ten en cuenta que verificamos errores tanto con malloc como con realloc y devolvemos NULL en caso de fallo. Además, recuerda liberar la nueva cadena en la función main después de usarla.

Comments are closed.