¿Cómo puedo hacer una función para borrar una cadena C y/o liberar la memoria asignada? ¿Por qué el código siguiente no funciona?

void freeStr(char** str) {
    free(*str);
}
int main() {
    char* str = "some string";
    freeStr(&str);
    printf("%s", str);
    return 0;
}
  • Sólo puede utilizar free() sobre indicadores que se usa malloc() antes.
  • dicho esto, el valor del puntero debe ser suficiente… no se necesita un puntero a un puntero. Usted no puede modificar de forma segura los datos de un literal de cadena, desde su const char[], y usted también no debe free ya que no malloc él… ni siquiera en el montón.
  • Siéntase libre de upvote y/o aceptar las respuestas que he encontrado muy útil.
  • Usted dice, yo debería de uso libre(str) en lugar de(*str) en función de freeStr(), derecho?
InformationsquelleAutor groove | 2012-09-05

5 Comentarios

  1. 10

    Puede ni libres ni borrar la memoria de la matriz en la que un literal de cadena indica.

    Sin embargo, a perder el acceso a ella, todo lo que necesita es cambiar el puntero que ha almacenado su dirección en:

    str = NULL; //in main
    //or
    *str = NULL; //in freeStr
  2. 4

    Usted podría encontrar que es útil para ir a las C FAQ – malloc sección.

    Como otros han señalado, no puede liberar o modificar los literales de cadena ya que se suelen colocar en leer sólo las secciones de la memoria. Sin embargo, si desea borrar y free() memoria asignada dinámicamente, tendría que hacer algo como lo siguiente:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define LENGTH  20
    
    void freeStr(char **str)
    {
        free( *str );
        *str = NULL;   
    }
    
    int main() {
    
        char *str = malloc( sizeof(char) * LENGTH);
    
        //clear that allocated memory
        memset( str, 0x00, LENGTH );
    
        //Put some text into the memory
        strncpy( str, "Some text", LENGTH-1 );
    
        printf("Before: %s\n", str);
    
    
        freeStr(&str);
        //string is now NULL and the memory is free.
        printf("After: %s\n", str);
    
        return 0;
    }
    • Es el uso de memset() debe aquí? (Estoy confundido, porque ponemos un poco de texto en la memoria justo después de eliminarla).
    • No se necesita. Pongo allí sólo para mostrar cómo borrar la memoria asignada.
    • por qué usted necesita para utilizar *str = NULL;? ¿por qué utilizar free( *str ); solo es no borrar la memoria(ya que estamos desasignar la memoria)? Por qué somos capaces de obtener la cadena de los contenidos de la memoria que ya está liberado o eliminado? Puede usted por favor explique en detalle?
  3. 4

    La cadena asignada en el CONST_DATA sección (no se puede modificar) y, por lo tanto, usted no llamada gratuita en él.

    Que parte de la memoria se asigna en tiempo de compilación y es de sólo lectura. Que parte de la memoria aún mantiene "some string\0"

    La CONST_DATA sección, en la asamblea es como los datos del segmento (DS), que contiene global y estático (sólo lectura) variables inicializadas en el momento de la compilación en sí. Que no cambio durante el tiempo de ejecución, y siendo asignado a la ejecución del programa.

    • Um, tu último párrafo está mal. Los programas no sobrescribir otros programas de la memoria. Además, la OP no es realmente libre en la memoria.
    • él dice que «Podría». Estoy de acuerdo con él en que cualquier dirección física gama desasignado puede en otros programas por un sistema operativo.
    • Sí, pero ya no sería asignada en su espacio de direcciones, y no puede ser leído o escrito.
    • Se puede leer todavía, siempre y cuando el usuario tiene un puntero a él. La escritura no han funcionado, como lo fue en el CONST_DATA sección de todos modos.
    • parte de la memoria se asigna en tiempo de compilación y es de sólo lectura. por favor, Puedes elaborar todo esto, que me ayudará a entender más sobre la asignación de memoria en tiempo de compilación? Según mi entendimiento, en tiempo de compilación vamos a crear algunos de direcciones virtuales y las variables vinculadas a esta dirección virtual (memoria de pila?), vamos a conseguir original de la memoria en tiempo de ejecución de un programa? Entonces, ¿dónde está esta memoria de sólo lectura, en virtud de la cual la sección de diseño de memoria esta «memoria de sólo lectura de la variable’ va? Por favor explique.
  4. 2

    Las respuestas son muy buenas, pero hay algunos puntos que se han perdido o se omite.
    Tu pregunta es un poco vaga.

    Si quieres borrar una cadena C sobrescribir el espacio de memoria que apunta con bytes nulos. Usted sólo puede free() una cadena C que ha sido asignado por el asignador de montón de a través de una llamada a uno de los asignador de montón de funciones tales como malloc(), calloc() o realloc() etc.

    Así que si usted asigna una cadena con malloc(), o uno de los otros del montón de asignación de funciones, como y, a continuación, copiar una cadena de caracteres en, usted podría borrar por llamar memset(), pero aún así, usted entonces tiene que llamar free() de liberar la memoria el montón.

    Por ejemplo:

    char* strPtr = malloc(32); //allocate 32 bytes of storage off the heap
    strcpy(strPtr, "test");    //copy a string into the newly allocated block on the heap
    memset(strPtr, 0, 32);     //clear the allocated block
    free(strPtr);              //return the allocated block to the heap

    También, tenga en cuenta que C utiliza el ámbito de bloque y no tiene explícitamente desasignar las matrices que fueron declaradas con el almacenamiento predeterminado de la clase, auto, ya que se desprendió del marco de pila cuando ese bloque sale del ámbito.

    void foo() {
        char strArray[32];          //this is a stack allocation
        strcpy(strArray, "test");   //copy a string onto the stack
        return;                     //no call to free() required
    }

    Por último, otro método de asignación es estático. Cuando utilice la declaración:

    char* str = "literal string";

    El espacio para la cadena «cadena literal» reside en un asignados estáticamente segmento que nunca debe ser escrito. En algunas plataformas, obtendrá una violación de segmento si intenta escribir a ese segmento de la memoria. Usted no debe tratar de borrar los bloques de memoria que se asignan estáticamente como no hay ninguna garantía de que el segmento de las que están asignadas en se puede escribir.

    • ¿Tengo que usar memset() antes de que free()? ¿El uso de free() sin memset() causa una pérdida de memoria?
    • no, no. memset() simplemente sobrescribe el contenido de la memoria intermedia con bytes nulos. la única entrada que el asignador de montón de necesidades para hacer de la liberación de ese bloque de memoria en el heap es la dirección. tenga en cuenta también que el asignador no automáticamente a cero el búfer antes de devolver un puntero a su código. esta eventualidad se produce todos los tipos de comportamiento interesante :).
  5. 2

    http://en.cppreference.com/w/c/memory/free

    void free( void* ptr );

    Desasigna el espacio previamente asignado por malloc(), calloc() o realloc(). Si ptr es apuntador null, la función no hace nada.

    Su cadena no está asignada con cualquiera de estas funciones. Creo que es de esta manera.

    void freeStr(char **str) {
        *str = NULL;
    }
    int main() {
        char* str = (char *)"some string";
        printf("Before: %s\n", str);
        freeStr(&str);
        printf("After: %s\n", str);
        return 0;
    }
    • Que en realidad no hace nada a la original puntero. El puntero se pasa por valor.
    • no hay que hacerlo nunca más.
    • Se olvidó de referencia, gracias chris. Wow Griwes, gracias por esa info, de verdad.
    • usted puede utilizar delete si no uso new y usted no puede usar free si no uso malloc,calloc, realloc
    • SSpoke, yo no estoy usando eliminar ni libre, sólo invalidar puntero.
    • Que el código es incorrecto. Aviso de la C de la etiqueta. Este es el código correcto para el puntero NULL. pastebin.com/YxrP4SKZ
    • He compilado y funciona. Por cierto, voy a editarlo, gracias Quimera.
    • Eres muy bienvenido!

Dejar respuesta

Please enter your comment!
Please enter your name here