2008-11-04 6 views
12

Si declaro un búfer de caracteres borrado automático temporal utilizando¿Es malo usar auto_ptr con el nuevo char [n]

std::auto_ptr<char> buffer(new char[n]); 

continuación, el búfer se elimina automáticamente cuando el buffer se sale del ámbito. Supongo que el buffer se borra usando delete.

Sin embargo, el búfer se creó utilizando new [], y por lo tanto estrictamente hablando, el búfer debe eliminarse utilizando delete [].

¿Qué posibilidad hay de que esta falta de coincidencia pueda causar una pérdida de memoria?

Respuesta

19

El comportamiento de invocar eliminar en un puntero asignado con new [] es undefined. Como suponía, auto_ptr does call delete cuando el puntero inteligente se sale del alcance. No se trata solo de pérdidas de memoria de las que tiene que preocuparse: son posibles los bloqueos y otros comportamientos extraños.

Si no necesita transferir la propiedad del puntero, la clase scoped_array de Boost puede ser lo que está buscando.

6

La llamada a eliminar en los datos asignados con la nueva [] no está definida. Esto significa que el compilador puede generar código que puede hacer cualquier cosa. Sin embargo, en este caso, probablemente funcione, ya que no es necesario destruir los caracteres individuales de la matriz, solo la matriz misma.

Aún como este comportamiento no está definido, recomendaría utilizar std::vector<char> o boost::scoped_array<char>/boost::shared_array<char>. Todas son opciones perfectamente viables y superiores para usar std::auto_ptr<> en este caso. Si usa std::vector, también tiene la posibilidad de aumentar dinámicamente el búfer si es necesario.

10

Usaría un vector de char como buffer.

std::vector<char> buffer(size); 

read(input,&buffer[0],size); 

Básicamente, no desea llamar a nuevo si no es necesario.
Un vector proporciona un búfer de tiempo de ejecución que puede usar como una matriz (búfer).

La mejor parte es que el vector se limpia después de sí mismo y el estándar garantiza que todos los elementos en el vector estarán en contigious storage. Perfecto para un buffer.

O más formaly la garantía es:

(&buffer[0]) + size == (&buffer[size]) 
5

¿Hay una buena razón para no usar std :: string? std :: vector, como otros han sugerido? Lo que estás haciendo está mal, pero sin saber lo que estás tratando de hacer es más difícil recomendar otra cosa.

0

Esto parece tremendamente complejo para una solución muy simple. ¿Qué le pasa usando

char *c=new char[n] 

aquí y luego eliminándolo? O, si necesita una solución un poco más dinámica,

vector<char> c 

navaja de Occam, hombre.:-)

+1

El punto es para garantizar la eliminación. Usar un puntero/matriz inteligente es seguro contra errores de programación normales, además de ser lo suficientemente inteligente como para liberar la memoria cuando ocurren excepciones. El uso directo de matrices C es una pérdida de memoria. – Diastrophism

+1

El punto es que queremos garantizar la eliminación. Por lo tanto, sin preparar RAW nuevo no es una buena respuesta. std :: vector por otro lado es una buena respuesta –

4

Sí, está mal. Envuelva con una envoltura trivial.

typedef< typename T_ > 
struct auto_vec{ 
    T_* t_; 
    auto_vec(T_* t): t_(t) {} 
    ~auto_vec() { delete[] t_; } 
    T_* get() const { return t_; } 
    T_* operator->() const { return get(); } 
    T_& operator*() const { return *get(); } 
    /* you should also define operator=, reset and release, if you plan to use them */ 
} 

auto_vec<char> buffer(new char[n]); 
2

Han pasado unos años desde que se formuló la pregunta.

Pero llegué a esta página de una búsqueda, por lo que pensé que también podría señalar: std :: unique_ptr, la sustitución de C++ 11 para auto_ptr, puede manejar la eliminación de objetos creados con el nuevo [].

hay dos versiones de std :: unique_ptr: 1) Gestiona la vida útil de un único objeto (por ejemplo, asignado con nuevo) 2) Gestiona el tiempo de vida de un matriz asignada dinámicamente de objetos (por ejemplo, asignado con la nueva [])

cppreference unique_ptr

+0

¿No sería eso específico para "MSDN" (cl es el nombre de ese compilador, sin embargo) –

+0

Lo suficiente. Se actualizó la referencia para que sea C++ general en lugar de específica de Microsoft-STL. Las otras respuestas estuvieron bien en 2008 cuando me las preguntaron por primera vez, pero ahora que auto_ptr ya no está en uso, solo espero que ningún webbuffer novato llegue a esta página y piense que necesitan mejorar su envoltura o cualquier otra cosa cuando la buena solución esté en STL gratis. ahora. – Daryn

Cuestiones relacionadas