Hace std:: vector.clear () ¿borrar (memoria libre) en cada elemento?


Considere este código:

#include <vector>

void Example()
{
    std::vector<TCHAR*> list;
    TCHAR* pLine = new TCHAR[20];
    list.push_back(pLine);
    list.clear();    // is delete called here?
    // is delete pLine; necessary?
}

Hace una lista.¿clear () llama a delete en cada elemento? Es decir, tengo que liberar la memoria antes / después de la lista.clear()?

 57
Author: Ignas Limanauskas, 2009-02-27

6 answers

No (tienes que hacer el borrado tú mismo al final como sugieres en tu ejemplo ya que la destrucción del puntero calvo no hace nada). Pero puedes usar un puntero inteligente boost [u otro modismo basado en RAII] para hacer que haga Lo Correcto (auto_ptr no funcionaría correctamente en un contenedor ya que tiene un comportamiento incompatible bajo copiar, etc.), pero asegúrese de entender las trampas de tales punteros inteligentes antes de su uso. (Como menciona Benoit, en este caso, basic_string es lo que realmente estás buscando aqui.)

Habiendo dicho que hay una necesidad de entender las trampas de los punteros inteligentes, hacer que se encarguen de la gestión de la memoria implícitamente para que no tenga que hacerlo explícitamente es mucho menos propenso a errores.

EDITAR: Sustancialmente revisado para abarcar los elementos que Benoit trajo a su respuesta mucho más completa, gracias a la fuerte insistencia de The Earwicker y James Matta - ¡gracias por empujarme a hacer la debida diligencia en esto!

 31
Author: Ruben Bartelink,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-27 22:48:08

Std::vector llama al destructor de cada elemento que contiene cuando se llama a clear (). En su caso particular, destruye el puntero pero los objetos permanecen.

Los punteros inteligentes son el camino correcto, pero tenga cuidado. auto_ptr no se puede usar en contenedores std. boost:: scoped_ptr tampoco puede. boost:: shared_ptr puede, pero no funcionará en tu caso porque no tienes un puntero a un objeto, en realidad estás usando una matriz. Así que la solución a su problema es utilizar boost::shared_array.

Pero sugiero que use std::basic_string en su lugar, donde no tendrá que lidiar con la administración de memoria, mientras sigue obteniendo los beneficios de trabajar con una cadena.

 48
Author: Benoît,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-08 08:43:22

Simplemente podrías escribir una función de plantilla simple que haga esto por ti:

template <class T>
void deleteInVector(vector<T*>* deleteme) {
    while(!deleteme->empty()) {
        delete deleteme->back();
        deleteme->pop_back();
    }

    delete deleteme;
}

Tal vez algo aquí es una mala práctica, pero no lo creo. A mí me parece bien, aunque los comentarios siempre son agradables.

 8
Author: Robert Massaioli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-16 04:47:33

Aquí hay una forma en la que puedes decir que no lo hace - pruébalo en una clase que no está completamente definida:

#include <vector>
class NotDefined;

void clearVector( std::vector<NotDefined*>& clearme )
{
    clearme.clear();    // is delete called here?
}

Si este fragmento compila, entonces no puede estar llamando al destructor, porque el destructor no está definido.

 7
Author: tfinniga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-27 13:32:18

No. No lo hace, ya que no hay garantía de que no esté utilizando el puntero en ningún otro lugar. Si no fuera una variable puntero, los liberaría (llamando al destructor)

 5
Author: Mehrdad Afshari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-27 09:29:13

También puede usar la Biblioteca de Contenedores de Puntero de Impulso . No se recomienda específicamente aquí (de nuevo porque está utilizando matrices en lugar de objetos individuales, aunque std::string se encargaría de eso), pero es una biblioteca útil y poco conocida que resuelve el problema indicado en el título.

 0
Author: Head Geek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-27 18:56:52