2010-03-24 14 views
19

Estoy tratando de escribir una clase de contenedor que use asignadores de STL. Lo que actualmente hago es tener un miembro privadoCómo usar std :: allocator en mi propia clase de contenedor

std::allocator<T> alloc_; 

(esta tarde será templated de manera que el usuario puede elegir un factor de imputación diferente) y luego llamar

T* ptr = alloc_.allocate(1,0); 

para obtener un puntero a una nueva asignó el objeto 'T' (y utilizó alloc_.construct para llamar al constructor; vea la respuesta a continuación). Esto funciona con la biblioteca GNU C++.

Sin embargo, con STLPort en Solaris, esto no hace lo correcto y conduce a todo tipo de errores bizarros de corrupción de memoria. Si en cambio hago

std::allocator_interface<std::allocator<T> > alloc_; 

entonces todo está funcionando como debería.

¿Cuál es la forma correcta de usar stl :: allocator? La versión de STLPort/Solaris no compila con g ++, pero es g ++ ¿verdad?

+7

No hay nada llamado 'allocator_interface' en la biblioteca estándar. – AraK

Respuesta

8

Algo que podría querer hacer es tener su propia allocator personalizada que pueda usar para ver cómo interactúan los contenedores estándar con los asignados. Stephan T. Lavavej publicó una bonita y simple llamada mallocator. Colocarlo en un programa de prueba que utiliza varios contenedores STL y se puede ver fácilmente cómo el asignador es utilizado por los contenedores estándar:

No todas las funciones de interfaz en la mallocator (tales como construct() y destroy()) están instrumentados con salida de rastreo, por lo que es posible que desee eliminar declaraciones de rastreo para ver más fácilmente cómo los contenedores estándar pueden usar esas funciones sin recurrir a un depurador.

Eso debería darle una buena idea de cómo se espera que sus contenedores usen un allocator personalizado.

+0

desafortunadamente no rastrea 'construct', que es la función que estaba fallando en usar: -/ –

+0

Eso es cierto (mencioné esa falla en mi respuesta), y tenía la intención de que mi respuesta fuera más o menos una barra lateral a su respuesta que señala el problema directamente. Lavavej publicó el 'mallocator' como un simple ejemplo de un asignador personalizado. Estaba proponiendo que también podría usarse como una forma fácil de obtener información sobre cómo los contenedores usan los asignadores, pero que podrían necesitarse algunas modificaciones menores para mejorar el rastreo con ese fin. –

16

Necesita asignar y construir con el asignador. Algo como esto:

T* ptr = alloc_.allocate(1,0); 
alloc_.construct(ptr, value); 

Muchas cosas están francamente rotas si no comienzas con un objeto construido correctamente. Imagine un std::string asignado pero no construido. Cuando intente asignarlo, primero tratará de limpiar sus contenidos anteriores liberando algunos datos, que serán, por supuesto, valores basura del montón y el bloqueo.

+0

Sí, lo sé, de hecho lo hice, aunque utilicé la ubicación nueva en lugar de std :: allocator :: construct (que probablemente no sea recomendable, así que lo cambié ahora). Sin embargo, resulta que STLPort 4.x no sabe acerca de std :: allocator :: construir ya sea ... –

+0

Si STLPort no tiene 'std :: allocator :: construct', entonces está roto, no te molestes incluso usándolo. Puedo decir con certeza que 5.1.5 (la versión que tengo instalada lo tiene y funciona bien). –

+1

Miré para satisfacer mi curiosidad, STLPort 4.x ** does ** tiene estándares adecuados conformes 'std :: allocator'. En 4.6, la función 'construct' se encuentra en la línea 365 de' stlport/stl/_alloc.h'.Si no funciona, su instalación no es correcta. –

Cuestiones relacionadas