C语言 根据以下理解,自定义对齐分配应如何工作

drkbr07n  于 2023-03-17  发布在  其他
关注(0)|答案(1)|浏览(113)

我试着理解如何在post下面引用aligned malloc,
How to allocate aligned memory only using the standard library?
存在基本上针对16字节对齐执行此操作的方法,返回的内存使用以下公式计算,

((uintptr_t)mem+16-1) & ~ (uintptr_t)0x0F;

我没有得到公认的答案是使用1024字节内存分配,因为它已经是16字节对齐。这种理解正确吗?
内存未对齐值不应该是1026或1029字节吗?基本上需要使其成为16的倍数。
下面的示例代码怎么样,

#include <stdio.h>
#include <stdlib.h>

void myalignmalloc(size_t size, int align)
{
    size_t ext = size % align;
    size_t alignsize = size - ext + align; // memory divisible by align value
    printf("size: %ld alignsize: %ld\n", size, alignsize);
    // TODO: Add code use alignsize to allocate extra memory with alignment
}

//TODO: Add myfree function

int main(void)
{
    myalignmalloc(1031, 16);
    myalignmalloc(1031, 32);
    myalignmalloc(1061, 16);
    myalignmalloc(1061, 32);
    return 0;
}

//output
//size: 1031 alignsize: 1040
//size: 1031 alignsize: 1056
//size: 1061 alignsize: 1072
//size: 1061 alignsize: 1088

这是不是仅仅通过使内存成为对齐的倍数来给我们正确的内存大小?

b4lqfgs4

b4lqfgs41#

存在基本上针对16字节对齐执行此操作的方法,返回的内存使用以下公式计算,

((uintptr_t)mem+16-1) & ~ (uintptr_t)0x0F;

这不是计算内存的 * 数量 *,而是计算对齐的 * 地址 您链接到的方法总是比请求多分配15个字节(对于16字节对齐),以确保从返回块中最早对齐的16字节地址开始,至少有请求的字节数可用。
我没有得到公认的答案是使用1024字节内存分配,因为它已经是16字节对齐。这种理解正确吗?
在我看来很明显,可接受的答案是1039字节(1024+15)分配,而不是1024字节分配。并且不,不能保证malloc返回的指针将是16字节对齐的。保证是内存将适合于具有基本对齐要求的任何对象对齐,这很大程度上意味着实现将默认为任何类型的对象选择的最大对齐要求。这不需要超过1字节对齐。更可能是4或8字节对齐。
内存未对齐值不应该是1026或1029字节吗?基本上需要使其成为16的倍数。
我不懂你的意思。
下面的示例代码呢,[...]
这是不是仅仅通过使内存成为对齐的倍数来给我们正确的内存大小?
不可以。要确保分配的块足够大,从第一个align对齐的地址开始至少包含size字节,而不假设块本身的对齐大于1,必须分配size + (align - 1)字节,这不是示例代码要计算的内容。
顺便说一句,还要注意,这种方法有一个比语言规范不能保证它工作的事实更严重的问题(因为它很可能会)。问题是,当需要 * 释放 * 已分配内存时,free()函数要求您提供malloc()返回的指针值,而不是从它派生的对齐指针(如果它们不同)。因此,你需要以某种方式保留它。我能想到的最好的选择是确保保留足够的额外空间,这样你就可以在分配的块中存储“真实的”指针,就在对齐地址之前。

  • 或者至少,它声称这样做。C语言绝不保证这种方法会像宣传的那样工作,但在许多实现中,它会。

相关问题