在 MS Visual Studio 2013 中,我可以用什么代替 std::aligned_alloc?
What can I use instead of std::aligned_alloc in MS Visual Studio 2013?
我想使用 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;
}
在Windows中是_aligned_malloc和_aligned_free,可以在malloc.h。 std 实现(alignof/alignas)在 VS 2015 中。它在 2013 中不可用。
免责声明:我没有彻底测试这段代码。
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*)
字节来存储 sizeof(void*)
返回的指针 ::operator new
以便我们稍后释放它。
我们用::operator new
分配这块内存,并将返回的指针存储在allocated_mem
中。然后我们将 sizeof(void*)
字节添加到 allocated_mem
并将结果存储在 aligned_mem
中。至此,我们还没有对齐。
在#1 点,内存块和两个点如下所示:
aligned_mem (not actually aligned yet)
V
+-------------+-----------------------------------------+
|sizeof(void*)| size + alignment - 1 bytes |
+-------------+-----------------------------------------+
^
allocated_mem points here
std::align
调用调整 aligned_mem
以获得所需的对齐方式。在第 2 点,它现在看起来像这样:
aligned_mem (correctly aligned now)
V
+---------------------+---------------------------------+
| extra space | at least size bytes |
+---------------------+---------------------------------+
^
allocated_mem points here
因为我们从 allocated_mem
之后的 sizeof(void*)
字节开始,所以 "extra space" 至少是 sizeof(void*)
字节。此外,aligned_mem
与 void*
正确对齐,因此我们可以在它之前存储一个 void*
。在第 3 点,内存块看起来像这样
aligned_mem (returned to caller)
V
+---------------+-----+---------------------------------+
| | ^ | at least size bytes |
+---------------+--+--+---------------------------------+
^ |
allocated_mem value of allocated_mem
points here stored here
至于aligned_free
,它只是读取存储在那里的指针并将其传递给::operator delete
。
我想使用 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;
}
在Windows中是_aligned_malloc和_aligned_free,可以在malloc.h。 std 实现(alignof/alignas)在 VS 2015 中。它在 2013 中不可用。
免责声明:我没有彻底测试这段代码。
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*)
字节来存储 sizeof(void*)
返回的指针 ::operator new
以便我们稍后释放它。
我们用::operator new
分配这块内存,并将返回的指针存储在allocated_mem
中。然后我们将 sizeof(void*)
字节添加到 allocated_mem
并将结果存储在 aligned_mem
中。至此,我们还没有对齐。
在#1 点,内存块和两个点如下所示:
aligned_mem (not actually aligned yet)
V
+-------------+-----------------------------------------+
|sizeof(void*)| size + alignment - 1 bytes |
+-------------+-----------------------------------------+
^
allocated_mem points here
std::align
调用调整 aligned_mem
以获得所需的对齐方式。在第 2 点,它现在看起来像这样:
aligned_mem (correctly aligned now)
V
+---------------------+---------------------------------+
| extra space | at least size bytes |
+---------------------+---------------------------------+
^
allocated_mem points here
因为我们从 allocated_mem
之后的 sizeof(void*)
字节开始,所以 "extra space" 至少是 sizeof(void*)
字节。此外,aligned_mem
与 void*
正确对齐,因此我们可以在它之前存储一个 void*
。在第 3 点,内存块看起来像这样
aligned_mem (returned to caller)
V
+---------------+-----+---------------------------------+
| | ^ | at least size bytes |
+---------------+--+--+---------------------------------+
^ |
allocated_mem value of allocated_mem
points here stored here
至于aligned_free
,它只是读取存储在那里的指针并将其传递给::operator delete
。