你們都知道C++中能夠直接調用malloc請求內存被返回分配成功的內存指針,該指針指向的地址就是分配獲得的內存的起始地址。好比下面的代碼函數
int main() { void *p = malloc(1024); printf("0x%p\n", p); free(p); }
請求了一個大小爲1024的內存塊並打印出來,一切都很完美。
咱們看看這塊內存的地址。
測試
能夠看到,在64bit機器上,malloc默認行爲會將分配的地址以16-byte對齊,若是咱們想改變這種默認行爲,提供32-byte或者64-byte對齊,應該怎麼作呢?
指針
從C++17開始,可使用aligned_alloc函數達到這個目的,可是若是使用較老的C++版本,如C++14,C++11,咱們須要手動寫一個實現。
話很少說,先貼代碼以下,aligned_malloc和aligned_free,須要配合使用,不然會有內存泄漏問題。code
#include <memory> void* aligned_malloc(size_t size, size_t alignment) { size_t offset = alignment - 1 + sizeof(void*); void * originalP = malloc(size + offset); size_t originalLocation = reinterpret_cast<size_t>(originalP); size_t realLocation = (originalLocation + offset) & ~(alignment - 1); void * realP = reinterpret_cast<void*>(realLocation); size_t originalPStorage = realLocation - sizeof(void*); *reinterpret_cast<void**>(originalPStorage) = originalP; return realP; } void aligned_free(void* p) { size_t originalPStorage = reinterpret_cast<size_t>(p) - sizeof(void*); free(*reinterpret_cast<void**>(originalPStorage)); } int main() { void * p = aligned_malloc(1024, 64); printf("0x%p\n", p); aligned_free(p); return 0; }
添加一個測試程序,blog
#include <assert.h> void TestAlignedMalloc() { const int size = 100; const int alignment = 64; void* testArray[size]; for (int i = 0; i < size; ++i) { void * p = aligned_malloc(1024, alignment); assert((reinterpret_cast<size_t>(p) & (alignment - 1)) == 0); printf("0x%p\n", p); testArray[i] = p; } for (int i = 0; i < size; ++i) { aligned_free(testArray[i]); } } int main() { TestAlignedMalloc(); return 0; }
看看結果,
內存
分配的內存地址都是以64-byte爲邊界,而且分配的內存最後也被成功釋放了,函數是正確的。it
本小段主要向不大瞭解解決思路的小夥伴作一些簡單解釋,程序大佬能夠一笑而過哈。io
首先咱們要明確咱們的解決方案,既然malloc分配的指針地址不能達到咱們想要的字節對齊效果,咱們就本身來調整這個指針。因此咱們的作法是ast
這就是在C++中手動實現aligned_malloc的方法,但願你們在使用較老版本的C++的時候,有須要能夠用上。若是使用的版本是C++17以上,那麼仍是推薦使用系統自帶的方法。class