C++ 是否有一个linux版本的_aligned_realloc

C++ 是否有一个linux版本的_aligned_realloc,c++,c,linux,C++,C,Linux,有linux的等价物吗 我想使用realloc,这样我就不必在每次调整数据大小时都记住它。我被mmap困住了吗?我只使用过一次mmap有没有推荐的方法可以实现几次调整大小的内存?我假设我不能将mmap与alloc混合,我必须为第一次调整大小做memcpy?(或始终使用mmap) 下面的realloc并不总是对齐。我在(64位)linux下使用gcc和clang进行了测试 #include<cstdlib> #include<cstdio> #define ALIGNSIZ

有linux的等价物吗

我想使用realloc,这样我就不必在每次调整数据大小时都记住它。我被mmap困住了吗?我只使用过一次mmap有没有推荐的方法可以实现几次调整大小的内存?我假设我不能将mmap与alloc混合,我必须为第一次调整大小做memcpy?(或始终使用mmap)

下面的realloc并不总是对齐。我在(64位)linux下使用gcc和clang进行了测试

#include<cstdlib>
#include<cstdio>
#define ALIGNSIZE 64
int main()
{
    for(int i = 0; i<10; i++)
    {
        void *p = aligned_alloc(ALIGNSIZE, 4096);
        void *p2 = realloc(p, 4096+2048); //This doesn't always align
        //void *p3 = aligned_alloc(ALIGNSIZE, 4096/24); //Doesn't need this line to make it unaligned. 

        if (((long)p & (ALIGNSIZE-1)) != 0 || ((long)p2 & (ALIGNSIZE-1)) != 0)
            printf("%d %d %d\n", i, ((long)p & (ALIGNSIZE-1)) != 0, ((long)p2 & (ALIGNSIZE-1)) != 0);
    }
}
#包括
#包括
#定义对齐大小64
int main()
{

对于(int i=0;i<p>否),C++中既没有标准替代,也没有POSIX标准,也没有GNU C库。 以下是仅使用标准函数的概念证明:

void*
aligned_realloc_optimistic(
    void* ptr, std::size_t new_size, std::size_t alignment)
{
    void* reallocated = std::realloc(ptr, new_size);
    return is_aligned(reallocated, alignment) // see below
        ? reallocated
        : aligned_realloc_pessimistic(reallocated, new_size, new_size, alignment);
        // see below
}
正如评论中指出的:这有一个警告,在最坏的情况下,
std::realloc
可能无法重用Allion,并且碰巧返回一个未对齐的指针,然后我们分配两次

我们可以通过无条件分配、复制和释放来跳过realloc的尝试,从而消除双重分配的最坏情况和不分配的最佳情况:

void*
aligned_realloc_pessimistic(
    void* ptr, std::size_t new_size, std::size_t old_size, std::size_t alignment)
{
    void* aligned = std::aligned_alloc(alignment, new_size);
    std::memcpy(aligned, ptr, old_size);
    std::free(ptr);
    return aligned;
}
明显的问题是,我们必须知道常规再分配不需要的旧规模

依靠系统特定的功能,我们可以保持避免分配和避免双重分配的最佳情况,也不需要知道旧的大小:

void*
aligned_realloc_glibc(
    void* ptr, std::size_t new_size, std::size_t alignment)
{
    auto old_size = malloc_usable_size(ptr); // GNU extension
    return old_size >= new_size && is_aligned(ptr, alignment)
        ? ptr
        : aligned_realloc_pessimistic(ptr, new_size, old_size, alignment);
}
上面使用的助手函数:

bool is_aligned(void* ptr, std::size_t alignment)
{
    std::size_t space = 1;
    return std::align(alignment, space, ptr, space);
}
我被mmap困住了吗

如果您想获得最大的灵活性,没有比使用平台的低级分配机制更好的方法了


在这种情况下,您需要
mremap()
,可能需要使用
mremap\u MAYMOVE
。它完全满足您的需要(如果您需要大于页面的对齐方式,则需要手动处理)。

否,realloc()不保证任意对齐,只保证机器字。您能在问题中解释为什么需要特定对齐吗?
malloc
realloc
等保证返回适合作为当前平台上任何数据类型指针的地址。这意味着在64位系统上,它至少与a对齐适用于64位值的地址,即8字节的倍数。@Bodo但不适用于32/64/128字节对齐的simd适用数据。@epx不是“机器字”但最大自然对齐。通常大于一个词。@EricStotch在您的案例中,这可能并不重要,但如果有足够的背景信息,通常会有人为您的用例提出完全不同的解决方案。这就是为什么在问题中提供这些信息很有用。这也将有助于其他人请回答类似的问题,以了解您的问题并确定它是否符合他们的用例。这就是为什么我建议将您的评论中的信息添加到问题中。有时会进行多次重新分配……也许最好从一开始就将
对齐\u alloc
memcpy
,以及
免费
我想这取决于
realloc
能够避免分配的可能性。这是一种乐观的方法。如果有一种方法可以测试
realloc
是否会事先分配,我们都可以利用它并避免分配两次。如果我错了,请纠正我,但这不是“概念证明”吗危险?被
std::align
重新调整的指针将不能是
std::free
d,因为它不是任何分配函数返回的同一指针(
std::aligned\u alloc
std::realloc
等)@人类编译器指针不会被
std::align
调整,因为它没有被给予调整的空间。啊,我明白了。标准是否保证
size
0
值不会只返回
nullptr