¿Con qué propósito debo usar std::get_temporary_buffer
? Standard dice lo siguiente:
Obtiene un puntero de almacenamiento suficiente para almacenar hasta n objetos T adyacentes.
Pensé que el búfer se asignará a la pila, pero eso no es cierto. Según el estándar C ++, este búfer en realidad no es temporal. ¿Qué ventajas tiene esta función sobre la función global ::operator new
, que tampoco construye los objetos? ¿Tengo razón en que las siguientes declaraciones son equivalentes?
int* x;
x = std::get_temporary_buffer<int>( 10 ).first;
x = static_cast<int*>( ::operator new( 10*sizeof(int) ) );
¿Esta función solo existe para syntax sugar? ¿Por qué hay temporary
en su nombre?
En el Dr. Dobb's Journal, 1 de julio de 1996, se sugirió un caso de uso para implementar algoritmos:
Si no se puede asignar ningún búfer, o si es más pequeño de lo solicitado, el algoritmo aún funciona correctamente, simplemente se ralentiza.
std::get_temporary_buffer
quedará obsoleto en C ++ 17.Respuestas:
Stroustrup dice en "El lenguaje de programación C ++" ( §19.4.4 , SE):
También comienza la introducción a las dos funciones con:
... pero no parece proporcionar una definición de temporal o de largo plazo en ninguna parte.
Sin embargo, una anécdota en "De las matemáticas a la programación genérica" menciona que Stepanov proporcionó una implementación de marcador de posición falsa en el diseño STL original:
fuente
operator new
con argumentos sucesivamente más pequeños hasta que la asignación se realiza correctamente. No hay optimizaciones especiales allí.crazy_allocator
get_temporary_buffer
. Sin embargo, si recibimos menos de la cantidad solicitada (lo que sería una verdadera lástima) seguimos intentando hacer nuestro trabajo con el almacenamiento que tenemos. Podría ser mejor que detectarbad_alloc
excepciones provocadas por el intento de asignar más memoria de la disponible. Sin embargo, la utilidad real se mantiene y cae con una buena implementación.El tipo de biblioteca estándar de Microsoft dice lo siguiente ( aquí ):
fuente
El estándar dice que asigna almacenamiento para hasta
n
elementos. En otras palabras, su ejemplo podría devolver un búfer lo suficientemente grande para solo 5 objetos.Sin embargo, parece bastante difícil imaginar un buen caso de uso para esto. Quizás si está trabajando en una plataforma con mucha memoria limitada, es una forma conveniente de obtener "tanta memoria como sea posible".
Pero en una plataforma tan limitada, me imagino que pasaría por alto el asignador de memoria tanto como sea posible y usaría un grupo de memoria o algo sobre lo que tenga control total.
fuente
La función está obsoleta en C ++ 17, por lo que la respuesta correcta ahora es "sin ningún propósito, no la use".
fuente
ptrdiff_t request = 12 pair<int*,ptrdiff_t> p = get_temporary_buffer<int>(request); int* base = p.first; ptrdiff_t respond = p.sencond; assert( is_valid( base, base + respond ) );
responder puede ser menor que la solicitud .
size_t require = 12; int* base = static_cast<int*>( ::operator new( require*sizeof(int) ) ); assert( is_valid( base, base + require ) );
el tamaño real de la base debe ser mayor o igual para requerir .
fuente
Quizás (solo una suposición) tenga algo que ver con la fragmentación de la memoria. Si sigue asignando y desasignando mucho la memoria temporal, pero cada vez que lo hace, asigna algo de memoria prevista a largo plazo después de asignar la temperatura pero antes de desasignarla, puede terminar con un montón fragmentado (supongo).
Por lo tanto, el get_temporary_buffer podría estar destinado a ser un trozo de memoria más grande de lo que necesitaría que se asigna una vez (tal vez hay muchos trozos listos para aceptar múltiples solicitudes), y cada vez que necesita memoria, solo obtiene uno de los trozos. Para que la memoria no se fragmente.
fuente