c++ - ¿Es incorrecto usar auto_ptr con la nueva char[n]?
stl memory-leaks (8)
Si declaro un búfer de carácter temporal eliminado automáticamente utilizando
std::auto_ptr<char> buffer(new char[n]);
luego, el buffer se elimina automáticamente cuando el buffer se sale del alcance. Supongo que el buffer se borra usando delete.
Sin embargo, el buffer fue creado usando new [], y por lo tanto estrictamente hablando, el buffer debe ser eliminado usando delete [].
¿Qué posibilidad hay de que esta falta de coincidencia pueda causar una pérdida de memoria?
¿Hay alguna 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.
Eso produce un comportamiento indefinido (podría ser peor que la pérdida de memoria, por ejemplo, daño en el montón) con boost scoped_array o shared_array en su lugar.
Esto parece terriblemente complejo para una solución muy simple. ¿Qué te pasa usando
char *c=new char[n]
aquí, y luego eliminarlo? O, si necesita una solución un poco más dinámica,
vector<char> c
La navaja de Occam, hombre. :-)
Llamar a eliminar en datos asignados con nuevo [] no está definido. 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.
Sin embargo, dado que este comportamiento no está definido, recomiendo usar std::vector<char>
o boost::scoped_array<char> / boost::shared_array<char>
lugar. 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 crecer dinámicamente el buffer si es necesario.
Usaría un vector de char como buffer.
std::vector<char> buffer(size);
read(input,&buffer[0],size);
Básicamente, ni siquiera quiere 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 almacenamiento contiguo. Perfecto para un buffer.
O más formalmente, la garantía es:
(&buffer[0]) + size == (&buffer[size])
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] );
El comportamiento de llamar a eliminar en un puntero asignado con new [] no está definido . Como suponía, auto_ptr llama a eliminar 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.
Han pasado unos años desde que se hizo la pregunta.
Pero llegué a esta página desde una búsqueda, así que pensé que también podría tener en cuenta: std :: unique_ptr , el reemplazo de C ++ 11 para auto_ptr, puede manejar la eliminación de objetos creados con new [].
Hay dos versiones de std :: unique_ptr: 1) Gestiona la vida útil de un solo objeto (por ejemplo, asignada con new) 2) Gestiona la vida útil de una matriz de objetos asignada dinámicamente (por ejemplo, asignada con new [])