Namespaces
Variants

std:: align

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Definido en el encabezado <memory>
void * align ( std:: size_t alignment,

std:: size_t size,
void * & ptr,

std:: size_t & space ) ;
(desde C++11)

Dado un puntero ptr a un búfer de tamaño space , devuelve un puntero alineado según la alignment especificada para size número de bytes y disminuye el argumento space por el número de bytes utilizados para la alineación. Se devuelve la primera dirección alineada.

La función modifica el puntero solo si sería posible ajustar el número deseado de bytes alineados por la alineación dada en el búfer. Si el búfer es demasiado pequeño, la función no hace nada y devuelve nullptr .

El comportamiento es indefinido si alignment no es una potencia de dos.

Contenidos

Parámetros

alignment - la alineación deseada
size - el tamaño del almacenamiento a alinear
ptr - puntero al almacenamiento contiguo (un búfer) de al menos space bytes
space - el tamaño del búfer en el que operar

Valor de retorno

El valor ajustado de ptr , o valor de puntero nulo si el espacio proporcionado es demasiado pequeño.

Ejemplo

Demuestra el uso de std::align para colocar objetos de diferente tipo en memoria.

#include <iostream>
#include <memory>
#include <new>
template<std::size_t N>
struct MyAllocator
{
    std::byte data[N];
    std::size_t sz{N};
    void* p{data};
    MyAllocator() = default;
    // Nota: solo está bien definido para tipos de duración implícita
    template<typename T>
    T* implicit_aligned_alloc(std::size_t a = alignof(T))
    {
        if (std::align(a, sizeof(T), p, sz))
        {
            T* result = std::launder(reinterpret_cast<T*>(p));
            p = static_cast<std::byte*>(p) + sizeof(T);
            sz -= sizeof(T);
            return result;
        }
        return nullptr;
    }
};
int main()
{
    MyAllocator<64> a;
    std::cout << "allocated a.data at " << (void*)a.data
              << " (" << sizeof a.data << " bytes)\n";
    // Asignar un char
    if (char* p = a.implicit_aligned_alloc<char>())
    {
        *p = 'a';
        std::cout << "allocated a char at " << (void*)p << '\n';
    }
    // Asignar un int
    if (int* p = a.implicit_aligned_alloc<int>())
    {
        *p = 1;
        std::cout << "allocated an int at " << (void*)p << '\n';
    }
    // Asignar un int, alineado en un límite de 32 bytes
    if (int* p = a.implicit_aligned_alloc<int>(32))
    {
        *p = 2;
        std::cout << "allocated an int at " << (void*)p << " (32-byte alignment)\n";
    }
}

Salida posible:

allocated a.data at 0x7ffc654e8530 (64 bytes)
allocated a char at 0x7ffc654e8530
allocated an int at 0x7ffc654e8534
allocated an int at 0x7ffc654e8540 (32-byte alignment)

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 2377 C++11 alignment requería ser un valor de alineamiento fundamental o extendido soportado solo necesita ser una potencia de dos

Véase también

alignof (C++11) consulta los requisitos de alineación de un tipo
(operador)
alignas (C++11) especifica que el almacenamiento para la variable debe estar alineado por una cantidad específica
(especificador)
(desde C++11) (obsoleto en C++23)
define el tipo adecuado para usar como almacenamiento no inicializado para tipos de tamaño dado
(plantilla de clase)
informa al compilador que un puntero está alineado
(plantilla de función)