在MS Visual Studio 2013中我可以使用什么代替std :: aligned_alloc?

时间:2015-08-21 05:49:51

标签: c++ visual-studio-2013 dynamic-memory-allocation memory-alignment

我想使用C ++ 11 std::aligned_alloc,但遗憾的是它不适用于Microsoft Visual Studio 2013.

我正在考虑,intsead,我自己实施aligned_alloc。实现应该如何?以下例如没有编译,因为它无法从void*转换为void*&

 template<typename T>
 T* aligned_alloc( std::size_t size, std::size_t align )
 {
        T* ptr = new T[size + align];
        std::align(align, size, reinterpret_cast<void*>(ptr), align + size);
        return ptr;
 }

2 个答案:

答案 0 :(得分:8)

免责声明:我没有彻底测试此代码。

void* aligned_alloc(std::size_t size, std::size_t alignment){
    if(alignment < alignof(void*)) { 
        alignment = alignof(void*); 
    }
    std::size_t space = size + alignment - 1;
    void* allocated_mem = ::operator new(space + sizeof(void*));
    void* aligned_mem = static_cast<void*>(static_cast<char*>(allocated_mem) + sizeof(void*)); 
    ////////////// #1 ///////////////
    std::align(alignment, size, aligned_mem, space);
    ////////////// #2 ///////////////
    *(static_cast<void**>(aligned_mem) - 1) = allocated_mem;
    ////////////// #3 ///////////////
    return aligned_mem;
}

void aligned_free(void* p) noexcept {
    ::operator delete(*(static_cast<void**>(p) - 1));
}

说明:

如果对齐小于此值,则调整为alignof(void*),因为正如我们将看到的,我们需要存储(正确对齐的)void*

我们需要size + alignment - 1个字节来确保我们可以在那里找到具有正确对齐的size字节块,再加上一个额外的sizeof(void*)字节来存储{{1}返回的指针所以我们以后可以释放它。

我们使用::operator new分配此内存,并将返回的指针存储在::operator new中。然后,我们将allocated_mem个字节添加到sizeof(void*),并将结果存储在allocated_mem中。在这一点上,我们还没有调整它。

在#1点,内存块和两点看起来像这样:

aligned_mem

aligned_mem (not actually aligned yet) V +-------------+-----------------------------------------+ |sizeof(void*)| size + alignment - 1 bytes | +-------------+-----------------------------------------+ ^ allocated_mem points here 调用会调整std::align以获得所需的对齐方式。在第2点,现在看起来像这样:

aligned_mem

因为我们从 aligned_mem (correctly aligned now) V +---------------------+---------------------------------+ | extra space | at least size bytes | +---------------------+---------------------------------+ ^ allocated_mem points here 字节开始sizeof(void*)字节,所以“额外空间”至少为allocated_mem字节。此外,sizeof(void*)已正确对齐aligned_mem,因此我们可以在其前面存储void*。在#3点,内存块看起来像这样

void*

对于 aligned_mem (returned to caller) V +---------------+-----+---------------------------------+ | | ^ | at least size bytes | +---------------+--+--+---------------------------------+ ^ | allocated_mem value of allocated_mem points here stored here ,它只是读取存储在那里的指针并将其传递给aligned_free

答案 1 :(得分:2)

在Windows中,它可以在malloc.h中找到 _aligned_malloc _aligned_free 。 std实现(alignof / alignas)在VS 2015中。它在2013年没有。