What can I use instead of std::aligned_alloc in MS Visual Studio 2013?

后端 未结 2 1647
小鲜肉
小鲜肉 2021-01-13 09:37

I would like to use C++11\'s std::aligned_alloc, but unfortunately it isn\'t available with Microsoft Visual Studio 2013.

I\'m considering, intsead, im

相关标签:
2条回答
  • 2021-01-13 10:12

    Disclaimer: I didn't thoroughly test this code.

    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));
    }
    

    Explanation:

    The alignment is adjusted to alignof(void*) if it's less than that, because, as we will see, we need to store a (properly aligned) void*.

    We need size + alignment - 1 bytes to ensure that we can find a size byte block in there with the right alignment, plus an additional sizeof(void*) bytes to store the pointer returned by ::operator new so that we can free it later.

    We allocate this memory with ::operator new and store the returned pointer in allocated_mem. We then add sizeof(void*) bytes to allocated_mem and store the result in aligned_mem. At this point, we haven't aligned it yet.

    At point #1, the memory block and the two points look like this:

                  aligned_mem (not actually aligned yet)
                  V
    +-------------+-----------------------------------------+
    |sizeof(void*)|    size + alignment - 1  bytes          |
    +-------------+-----------------------------------------+
    ^
    allocated_mem points here
    

    The std::align call adjusts aligned_mem to obtain the desired alignment. At point #2, it now looks like this:

                          aligned_mem (correctly aligned now)
                          V
    +---------------------+---------------------------------+
    | extra space         |  at least size bytes            |
    +---------------------+---------------------------------+
    ^
    allocated_mem points here
    

    Because we started at sizeof(void*) bytes past allocated_mem, the "extra space" is at least sizeof(void*) bytes. Moreover, aligned_mem is correctly aligned for void*, so we can store a void* right before it. At point #3, the block of memory looks like this

                          aligned_mem (returned to caller)
                          V
    +---------------+-----+---------------------------------+
    |               |  ^  |  at least size bytes            |
    +---------------+--+--+---------------------------------+
    ^                  |
    allocated_mem      value of allocated_mem
    points here        stored here
    

    As to aligned_free, it simply reads the pointer stored there and passes it to ::operator delete.

    0 讨论(0)
  • 2021-01-13 10:22

    In Windows it's _aligned_malloc and _aligned_free, which can be found in malloc.h. The std implementation (of alignof/alignas) is in VS 2015. It's not available in 2013.

    0 讨论(0)
提交回复
热议问题