Tengo esta función:

char* ReadBlock(fstream& stream, int size)
{
    char* memblock;
    memblock = new char[size];
    stream.read(memblock, size);
    return(memblock);
}

La función es llamada cada vez que tengo que leer bytes de un archivo. Creo que asigna memoria nueva cada vez que lo use, pero ¿cómo puedo liberar la memoria una vez que se han procesado los datos dentro de la matriz? Puedo hacerlo desde fuera de la función? El procesamiento de datos mediante la asignación de los grandes bloques da un mejor rendimiento que la asignación y eliminación de pequeños bloques de datos?

Muchas gracias por tu ayuda!

  • +1. Esta es una gran pregunta! Es tocones de una gran cantidad de recién llegados a manual de asignación de memoria.
  • Esta es una terrible pregunta, los recién llegados deben aprender a utilizar un std::string o std::vector.
  • En lugar de aprender de cómo std::string y std::vector de trabajo bajo el capó? Creo que es una buena pregunta, aunque se me pueden estar sesgados debido a que es uno sigo teniendo yo, como no quiero empezar con el uso de azar bibliotecas sin saber lo que están haciendo.
InformationsquelleAutor Emer | 2010-06-30

6 Comentarios

  1. 15

    Matrices dinámicas se liberan mediante delete[]:

    char* block = ReadBlock(...);
    //... do stuff
    delete[] block;

    Idealmente sin embargo, usted no utilice el manual de gestión de la memoria aquí:

    std::vector<char> ReadBlock(std::fstream& stream, int size) {
        std::vector<char> memblock(size);
        stream.read(&memblock[0], size);
        return memblock;
    }
    • Con este método, cuando el vector objeto es devuelto, hace su constructor de copia se llama (quiero decir, ¿existen dos instancias en un punto)?
    • Depende, más probable es que nombre valor de retorno de la optimización de la, NRVO, dará el pistoletazo de en. Véase también el interesante Quiero Velocidad? Paso por valor..
    • Interesante post, pero es nombre engañoso. Casi suena como si estuvieran discutiendo de paso por valor, en lugar de pasar por referencia. Enlace cebo, supongo.
    • Si no es tan trivial como el ejemplo de arriba, yo siempre iba a usar el BOOST shared_ptr (o intrusive_ptr si el tipo de datos es una clase). Puede sonar pesado, pero conduce a la constante fuga de código libre (casi).
    • Luego shared_array<T> sería un mejor ajuste aquí, sin necesidad de una costumbre deleter.
    • Ah veo! Por lo tanto, si he leído bien, la norma permite una optimización que impide que un constructor de copia se llama incluso si la copia cto r tiene efectos secundarios?
    • Sí, es una notable excepción a la regla de no cambiar el comportamiento observable. RVO es observable, por ejemplo, con el registro de las declaraciones-en tanto cto r y copia-cto r con X f() { return X(); } X x = f(); (activado optimizaciones se supone). Si usted tiene un estándar práctico ver el artículo 12.8/15.

  2. 5

    Sólo delete[] el valor de retorno de esta función cuando haya terminado con él. No importa que usted está eliminando desde el exterior. Simplemente no se elimina antes de que haya terminado de utilizarla.

    • Tiene que ser delete[], no delete.
    • Ouch! Lo triste es que si se comete este error, el compilador no puede incluso detectar. Qué horrible el idioma. De todos modos, gracias. Voy a arreglar el post. (Aunque debe decirse que yo no estaba proponiendo toda la línea de código, justo lo que builtin de utilizar).
  3. 4

    Que puede llamada:

    char * block = ReadBlock(stream, size);
    delete [] block;

    Pero… eso es un montón de asignación del montón para no ganar. Considerar la adopción de este enfoque

    char *block = new char[size];
    while (...) {
      stream.read(block, size);
    }
    delete [] block;

    * * * * Nota, si size puede ser una compilación de constante de tiempo, usted puede pila de asignar block.

    • Sólida llamada en pasar estática puntero a la función. +1
    • Variable tamaño de las matrices no son ISO C++, es un GCC extensión.
    • Quien dice que el tamaño no es tiempo de compilación?
    • La definición de la función dice que: char* ReadBlock(…, int size);
    • Esto eliminaría la necesidad de la función, de todos modos, uno de los puntos… comentó.
    • No me acaba de memoria si yo no lo borre ya leer bloques de memoria?
    • Esteban, ¿por qué ha vuelto new int[size] en lugar de new char[size]?
    • Mmmm, buena pregunta. Gracias fija. 😉
    • Se puede reutilizar el mismo tampón, si la aplicación lo permite (si que es cierto que no está claro a partir de tu pregunta). Si no es posible reutilizar el mismo buffer, entonces usted debe utilizar un enfoque diferente, como devolver una cadena.

  4. 1

    Sí. Usted puede llamar a eliminar desde fuera de la función. En este caso, sugiero el uso de un std::string, así que usted no tiene que preocuparse acerca de la gestión de ti mismo?

    • Ok, pero no puedo utilizar cadenas, porque de leer. istream& leer ( char* s, streamsize n );
    • A continuación, utilice un vector en su lugar. Lo sentimos, no se dio cuenta de que.
  5. 1

    primera cosa a tener en cuenta: la memoria asignada con new y delete es completamente global. las cosas no se eliminan automáticamente cuando punteros de ir fuera de alcance, o una función que se sale. mientras usted tiene un puntero a la asignación (tales como el puntero de ser devuelto a) se puede eliminar cuando y donde quiera. el truco, es solo makeing seguro de que otras cosas, no se elimina con la que conocer.

    que es un beneficio con el tipo de función de la estructura de la fstream la función de lectura tiene. es bastante claro que todos los que la función se va a hacer es leer ‘tamaño’ número de bytes en el buffer que ofrecer, no importa si ese buffer ha sido asignado con la nueva, ya sea estática o búfer global, o incluso un búfer local, o incluso simplemente un puntero a una estructura local. y también es bastante claro que la función va a hacer nada más con el tampón de pasar una vez que se leen los datos.

    por otro lado, tomar la estructura de su ReadBlock función; si usted no tiene el código para que sería difícil de averiguar exactamente lo que estaba regresando. es devolver un puntero a la nueva gustaría memoria? si así es, se espera que para eliminarlo? va a eliminar es el ser? si es así, ¿cuándo? es incluso un nuevo puntero? es que acaba de regresar de una dirección para algunos compartidos estáticos buffer? si es así, cuando el búfer de ser válida (por ejemplo, sobrescritos por otra cosa)

    de mirar el código para ReadBlock, es claro que se está devolviendo un puntero a la nueva gustaría memoria, y se espera que para eliminarlo, cuando cada vez que haya terminado con él. que búfer nunca será sobrescrito o de ser válida hasta que lo elimine.

    velocidad sabio, que es la otra ventaja de fsream.lectura de «ordenar el buffer’ enfoque: tienes la opción de cuando se asigna la memoria. si usted va a «leer los datos, proceso, borrar búfer de lectura de datos de proceso de borrar búfer, ect…. «va a ser mucho más eficiente que acaba de asignar un búfer (el máximo tamaño que usted necesita, este va a ser el tamaño de la más grande de la sola lectura) y que sólo use para todo, como lo sugirió Esteban.

  6. 0

    Cómo sobre el uso de un static char* memblock; será inicializado sólo una vez y no lo puedo asignar memblock un nuevo espacio cada vez.

Dejar respuesta

Please enter your comment!
Please enter your name here