std:: align
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Défini dans l'en-tête
<memory>
|
||
|
void
*
align
(
std::
size_t
alignment,
std::
size_t
size,
|
(depuis C++11) | |
Étant donné un pointeur ptr vers un tampon de taille space , retourne un pointeur aligné selon l' alignment spécifié pour size octets et décrémente l'argument space du nombre d'octets utilisés pour l'alignement. La première adresse alignée est retournée.
La fonction modifie le pointeur uniquement s'il serait possible de placer le nombre d'octets souhaité aligné selon l'alignement donné dans le tampon. Si le tampon est trop petit, la fonction ne fait rien et retourne nullptr .
Le comportement est indéfini si alignment n'est pas une puissance de deux.
Table des matières |
Paramètres
| alignment | - | l'alignement souhaité |
| size | - | la taille du stockage à aligner |
| ptr | - |
pointeur vers un stockage contigu (un tampon) d'au moins
space
octets
|
| space | - | la taille du tampon dans lequel opérer |
Valeur de retour
La valeur ajustée de ptr , ou la valeur du pointeur nul si l'espace fourni est trop petit.
Exemple
Illustre l'utilisation de
std::align
pour placer des objets de types différents en mémoire.
#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; // Note: only well-defined for implicit-lifetime types 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"; // Allocate a char if (char* p = a.implicit_aligned_alloc<char>()) { *p = 'a'; std::cout << "allocated a char at " << (void*)p << '\n'; } // Allocate an int if (int* p = a.implicit_aligned_alloc<int>()) { *p = 1; std::cout << "allocated an int at " << (void*)p << '\n'; } // Allocate an int, aligned at a 32-byte boundary if (int* p = a.implicit_aligned_alloc<int>(32)) { *p = 2; std::cout << "allocated an int at " << (void*)p << " (32-byte alignment)\n"; } }
Sortie possible :
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)
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | S'applique à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 2377 | C++11 |
alignment
devait être une valeur d'alignement fondamentale ou étendue supportée
|
doit uniquement être une puissance de deux |
Voir aussi
alignof
(C++11)
|
interroge les exigences d'alignement d'un type
(opérateur) |
alignas
(C++11)
|
spécifie que le stockage de la variable doit être aligné selon une valeur spécifique
(spécificateur) |
|
(depuis C++11)
(obsolète en C++23)
|
définit le type approprié pour une utilisation comme stockage non initialisé pour des types de taille donnée
(modèle de classe) |
|
(C++20)
|
informe le compilateur qu'un pointeur est aligné
(modèle de fonction) |