studio reales proyectos programacion libro introducción incluye herramientas fundamentos fuente español código con avanzado aplicaciones c++ visual-c++ com memory-alignment

c++ - reales - libro de android studio en español pdf



¿Cuáles son las limitaciones de alineación del operador estándar global predeterminado nuevo? (3)

Estoy trabajando en un código anterior que usa el tipo CComBSTR de ATL. Lo estoy cambiando para que compile usando Visual C ++ Express Edition, que no viene con ATL. Solo usé un subconjunto muy pequeño de CComBSTR , por lo que hacer esto es bastante simple.

Sin embargo, al asignar el bloque de memoria BSTR , necesito llenar los primeros cuatro bytes con un prefijo de 4 bytes de longitud. Me preocupa que si utilizo una new char[size] expresión new char[size] para asignar la memoria para la cadena, causaré fallas de alineación debido a que la matriz char asignada no tiene la alineación correcta para el prefijo de cuatro bytes.

¿Hay algo en el estándar que indique qué requisitos de alineación tienen los valores devueltos de los new ? Todo lo que veo en C ++ 11 son:

5.3.4 / 1 [expr.new]
Está definido por la implementación si los tipos sobrealineados son compatibles (3.11).

3.11 / 6 [basic.align]
El requisito de alineación de un tipo completo se puede consultar utilizando una expresión de alineación (5.3.6). Además, los tipos char, signed char y unsigned char tendrán el requisito de alineación más débil. [Nota: Esto permite que los tipos de caracteres se usen como el tipo subyacente para un área de memoria alineada (7.6.2) .- nota final]

Encuentro esto algo confuso: "requisito de alineación más débil" me dice "restricción mínimamente estricta sobre la alineación", pero la nota debajo de esto parece indicar que el estándar significa lo contrario.

¿Estoy seguro usando un new char[sizeof(uint32_t) + 2*(length + 1)] como un BSTR como este?

EDITAR : Me acabo de dar cuenta de que en este caso específico de BSTR , uno necesita usar SysAllocString para asignar la cadena de todos modos; pero aún estoy interesado en si está bien usar o no las new de esta manera.


5.3.4 / 1 [expr.new]

Está definido por la implementación si los tipos sobrealineados son compatibles (3.11).

Una cosa importante aquí: over-aligned significa más alineado que cualquier tipo incorporado. Por ejemplo, en la máquina de 64 bits, los punteros generalmente están alineados a 8 bytes y, por lo tanto, en las máquinas sobre alineadas significa que tienen una alineación estrictamente mayor que 8.

Por lo tanto, el over-aligned solo es motivo de preocupación cuando se utilizan tipos de vector, como los necesarios para las instrucciones SSE o AVX o algunas variantes de C / C ++ (como Open CL). En la programación diaria, los tipos que elabora desde los tipos incorporados nunca se alinean en exceso.

§3.11 Alineación [basic.align]

3 / Una alineación extendida se representa por una alineación mayor que alignof(std::max_align_t) . Está definido por la implementación si se admite cualquier alineación extendida y los contextos en los que son compatibles (7.6.2). Un tipo que tiene un requisito de alineación extendida es un tipo sobrealineado .

9 / Si una implementación no requiere una alineación extendida específica en un contexto específico, el programa está mal formado. Además, una solicitud de asignación de tiempo de ejecución del almacenamiento dinámico para el que no se puede cumplir la alineación solicitada se tratará como una falla de asignación.

Además, es habitual que los new devuelvan la memoria alineada a alignof(std::max_align_t) . Esto se debe a que el ::operator new regular ::operator new solo conoce el tamaño del objeto para asignar, no su alineación, y por lo tanto necesita satisfacer los requisitos de alineación más fuertes posibles en el programa.

Por otro lado, tenga cuidado con una matriz de caracteres asignada en la pila, no hay garantía de cuál sería su alineación.


Es un detalle de implementación, pero MSVC usa los asignadores del sistema operativo. HeapAlloc () para asignaciones de CRT, CoTaskMemAlloc () para contenedores de tipo COM como _bstr_t. Ambos se alinean por 8, tanto en código de 32 bits como de 64 bits.

Nunca debe asignar memoria para BSTR con el nuevo operador, el asignador COM debe utilizarse para garantizar que se eliminen utilizando el montón adecuado. Importante en cualquier escenario de interoperabilidad, que es donde se usa BSTR, es un tipo de Automatización estándar. Se requiere CoTaskMemAlloc / Free (), pero siempre use las funciones auxiliares BSTR para asegurarse de que se inicialicen correctamente. SysAllocString () y SysFreeString (). Use SysAllocStringLen () para tratar cadenas que contienen ceros incrustados.


Nunca debe intentar usar las funciones de gestión de memoria de C ++ para BSTR; solo deberían asignarse utilizando las funciones de familia SysAllocString() . Esto garantiza que quien obtenga un BSTR puede usar SysFreeString() y otras funciones de la familia en el BSTR obtenido. Si infringe este requisito, su programa tendrá un comportamiento indefinido.