variable libre cuando se usa malloc en c

CorePress2024-01-24  9

char **loadValues()
{
    char **toReturn;
    int i;
    toReturn = malloc(5 * sizeof(char *));
    for (i = 0; i < 5; i++)
    {
        toReturn[i] = malloc(25);              //Change the size as per your need
        strncpy(toReturn[i], "string", i + 1); //Something to copy
    }
    return toReturn;
}

Copié parte del código anterior. En él, el comando "toReturn" La variable se inicializa usando malloc. ¿No tenemos que "liberar" este comando "toReturn" variable?

¿No tenemos que liberar estas variables cuando las devolvemos en C? Todavía no pude encontrar una respuesta clara y no puedo encontrar una manera de liberarlas cuando las devuelva. ¿Alguien puede explicármelo?

No tienes que usar free() si estás en un sistema operativo moderno y no usas loadValues() demasiadas veces. c - ¿Qué sucede REALMENTE cuando no liberas después?malloc? - Stack Overflow Otra condición es que no tienes que satisfacer fichas como Valgrind.

- MikeCAT

27/03/2021 a las 20:01

2

Liberar lo que se va a devolver es una mala idea porque devolverlo significa que se utilizará más adelante y usar el búfer liberado es ilegal.

- MikeCAT

27/03/2021 a las 20:02

1

Eso es como darle tu número de teléfono anterior a alguien que te pide tu número

- klutt

27/03/2021 a las 20:06

3

Aparte: un peligro oculto. La función strncpy() no proporciona un terminador nulo si alcanza el límite de recuento y malloc() no inicializa la memoria que proporciona. Entonces no hay terminador.

Veleta

27/03/2021 a las 20:10

Gracias a todos. Aprendí más cosas.

- Kavishka Madhushan

28/03/2021 a las 13:50



------------------------------------

Supongo que tu pregunta es: ¿cómo la función que llama a loadValues ​​y recibe el puntero que devuelve puede liberar los valores cargados?

Si dejamos loadValues ​​como está ahora, la mejor solución es crear otra función, llamada freeValues ​​y llamarla cuando hayamos terminado con los valores:

void freeValues(char **values)
{
    for (i = 0; i < 5; i++)
    {
        free(values[i]);
    }
    free(values);
}

Entonces puedes hacer algo como esto en tu programa principal:

char **values = loadValues();
// ... use values for something
freeValues(values);

Otra opción es asignartoReturn usando una sola llamada a malloc, en cuyo caso se puede liberar simplemente llamando a free.

1

1

Aparte: en el espíritu de que freeNULL) está bien, sugerimos tolerar freeValues(NULL).

– chux - Reincorporar a Mónica

27/03/2021 a las 22:07



------------------------------------

No puedes liberar la memoria asignada dentro de la función y devolverlat datos para que puedan usarse fuera de la función. Pero aún puedes liberar() la memoria fuera de la función.

1

1

Eso es correcto, felicidades por tu primera respuesta y tu primer voto a favor.

-anastaciu

27/03/2021 a las 22:15



------------------------------------

¿No tenemos que "liberar" este comando "toReturn" variable?

Sí, eventualmente querrás liberar la memoria una vez que hayas terminado.

Aún no encuentro una respuesta clara y no encuentro la manera de liberarlo cuando lo devuelva. ¿Alguien puede explicármelo?

Cuando usas la función la asignas a un nuevo puntero, puedes usar este puntero, no solo para acceder al bloque de memoria que devolviste, sino también para liberarlo, ejemplo:

int main()
{
    char** values = loadValues();
    
    // do something with values

    // don't need them anymore
    for (int i = 0; i < 5; i++){
        free(values[i]);
    }
    free(values);
}

Tenga en cuenta que strncpy(toReturn[i], "string", i + 1); Probablemente no sea lo que desea, en cada iteración está copiando solo de 1 a 5 caracteres respectivamente, no la cadena completa y, lo que es más importante, no el terminador nulo.

El tercer argumento de strncpy debe ser la longitud de la "cadena" más 1 byte más para el terminador nulo, por lo que 7 en este caso. Alternativamente, si desea copiar sóloparte de la cadena, debe terminarla en nulo usted mismo.

Si el objetivo es copiar la cadena completa, puedes dejar que el compilador lo haga por ti:

//...
toReturn = malloc(5 * sizeof(char *));
for (i = 0; i < 5; i++)
{
    toReturn[i] = strdup("string");  // duplicate string and store it in toReturn[i]
}
//...

Por supuesto, todavía tienes que liberarlo tú mismo como en la primera situación.

1

Muchas gracias por tu respuesta. Lo tengo y aprendo más cosas.

- Kavishka Madhushan

28/03/2021 a las 13:47

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare