precedente per C++ 11 allineamento è stato trattato abbastanza semplice utilizzando il più grande allineamento dove il valore esatto era sconosciuto e malloc/calloc ancora funziona in questo modo. Ciò significa che l'allocazione di malloc è correttamente allineata per qualsiasi tipo.
allineamento errato può causare il comportamento non definito secondo lo standard ma ho visto compilatori x86 essere generosi e solo sanzionare con prestazioni inferiori.
Si noti che è anche possibile modificare l'allineamento tramite le opzioni di compilazione o direttive. (pacchetto pragma per VisualStudio per esempio).
Ma quando si tratta di nuova collocazione, quindi C++ 11 ci porta nuove parole chiave chiamati alignof e alignas. Ecco un codice che mostra l'effetto se l'allineamento massimo del compilatore è maggiore di 1. Il primo posizionamento nuovo è automaticamente buono ma non il secondo.
#include <iostream>
#include <malloc.h>
using namespace std;
int main()
{
struct A { char c; };
struct B { int i; char c; };
unsigned char * buffer = (unsigned char *)malloc(1000000);
long mp = (long)buffer;
// First placment new
long alignofA = alignof(A) - 1;
cout << "alignment of A: " << std::hex << (alignofA + 1) << endl;
cout << "placement address before alignment: " << std::hex << mp << endl;
if (mp&alignofA)
{
mp |= alignofA;
++mp;
}
cout << "placement address after alignment : " << std::hex <<mp << endl;
A * a = new((unsigned char *)mp)A;
mp += sizeof(A);
// Second placment new
long alignofB = alignof(B) - 1;
cout << "alignment of B: " << std::hex << (alignofB + 1) << endl;
cout << "placement address before alignment: " << std::hex << mp << endl;
if (mp&alignofB)
{
mp |= alignofB;
++mp;
}
cout << "placement address after alignment : " << std::hex << mp << endl;
B * b = new((unsigned char *)mp)B;
mp += sizeof(B);
}
immagino prestazioni di questo codice può essere migliorata con alcune operazioni bit per bit.
EDIT: sostituito costoso modulo di calcolo con operazioni bit per bit. Sperando ancora che qualcuno trovi qualcosa ancora più veloce.
fonte
2013-08-28 04:42:39
nuovo e malloc, per default, allineare indirizzo a 8 byte (x86) o 16 byte (x64), che è ottimale per la maggior parte dei dati complessi. Inoltre è il compito sizeof() di ottenere la struct size corretta ** con ** padding interno per l'allineamento, se necessario. –