将值存储在 malloc 和对齐的指针 C 后面

发布于 2025-01-17 02:31:25 字数 1451 浏览 4 评论 0原文

参考代码:https://embeddedartistry.com/blog/2017/ 02/22/generating-aligned-memory/

void * aligned_malloc(size_t align, size_t size)
{
    void * ptr = NULL;
    
    // We want it to be a power of two since
    // align_up operates on powers of two
    assert((align & (align - 1)) == 0);

    if(align && size)
    {
        /*
         * We know we have to fit an offset value
         * We also allocate extra bytes to ensure we 
         * can meet the alignment
         */
        uint32_t hdr_size = PTR_OFFSET_SZ + (align - 1);
        void * p = malloc(size + hdr_size);

        if(p)
        {
            /*
             * Add the offset size to malloc's pointer 
             * (we will always store that)
             * Then align the resulting value to the 
             * target alignment
             */
            ptr = (void *) align_up(((uintptr_t)p + PTR_OFFSET_SZ), align);

            // Calc`enter code here`ulate the offset and store it 
            // behind our aligned pointer
            *((offset_t *)ptr - 1) = 
                (offset_t)((uintptr_t)ptr - (uintptr_t)p);

        } // else NULL, could not malloc
    } //else NULL, invalid arguments

    return ptr;
}

我不明白这一行如何在 ptr 后面存储值。 “*((offset_t *)ptr - 1) = (offset_t)((uintptr_t)ptr - (uintptr_t)p);”

Reference code : https://embeddedartistry.com/blog/2017/02/22/generating-aligned-memory/

void * aligned_malloc(size_t align, size_t size)
{
    void * ptr = NULL;
    
    // We want it to be a power of two since
    // align_up operates on powers of two
    assert((align & (align - 1)) == 0);

    if(align && size)
    {
        /*
         * We know we have to fit an offset value
         * We also allocate extra bytes to ensure we 
         * can meet the alignment
         */
        uint32_t hdr_size = PTR_OFFSET_SZ + (align - 1);
        void * p = malloc(size + hdr_size);

        if(p)
        {
            /*
             * Add the offset size to malloc's pointer 
             * (we will always store that)
             * Then align the resulting value to the 
             * target alignment
             */
            ptr = (void *) align_up(((uintptr_t)p + PTR_OFFSET_SZ), align);

            // Calc`enter code here`ulate the offset and store it 
            // behind our aligned pointer
            *((offset_t *)ptr - 1) = 
                (offset_t)((uintptr_t)ptr - (uintptr_t)p);

        } // else NULL, could not malloc
    } //else NULL, invalid arguments

    return ptr;
}

I do not understand how this line stores value behind the ptr.
"*((offset_t *)ptr - 1) =
(offset_t)((uintptr_t)ptr - (uintptr_t)p);"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梨涡 2025-01-24 02:31:25

分配和计算后,ptr 包含该例程将返回给其调用者的值,该值是调用者用来存储其数据的地址。

(offset_t *)ptr 将此地址转换为 offset_t * 类型。

然后,(offset_t *)ptr - 1 计算内存中较早(低地址)一个 offset_t 对象距离的位置。

然后 *((offset_t *)ptr - 1) = …; 在该位置存储一个值。

After the allocation and calculation, ptr contains the value this routine will return to its caller, which is the address for the caller to use to store its data.

(offset_t *)ptr converts this address to the type offset_t *.

Then (offset_t *)ptr - 1 calculates a location in memory that is earlier (lower addressed) by the distance of one offset_t object.

Then *((offset_t *)ptr - 1) = …; stores a value in that location.

天涯离梦残月幽梦 2025-01-24 02:31:25

除了其他好的答案之外:

ptr = (void *)align_up(((uintptr_t)p + PTR_OFFSET_SZ),align);未定义行为奠定了基础(UB)因为 aligned_malloc() 不一定满足 max_align_t

malloc() 始终提供一个满足至少对齐到 sizeof(max_align_t) 要求的指针,并且许多代码都依赖于此。 aligned_malloc() 确实满足这一要求 - 它应该满足。

为了可移植性,不建议“按原样”使用此代码。

为了正确执行此操作,aligned_malloc()align_up() 必须考虑 max_align_tsize 的最大值。

void * aligned_malloc(size_t align, size_t size) {
  assert(...);
  if (size < sizeof(max_algin_t)) {
    size = sizeof(max_algin_t);
  }
  ...

In addition to other good answers:

ptr = (void *) align_up(((uintptr_t)p + PTR_OFFSET_SZ), align); lays the seeds for undefined behavior (UB) as aligned_malloc() does not certainly meet max_align_t.

malloc() always provides a pointer that meets this requirement of aligning to at least sizeof(max_align_t) and much code relies on that. aligned_malloc() does not certainly meet that - it should.

Do not recommend this code "as is" for portability.

To do this right, aligned_malloc() and align_up() must consider the maximum of both max_align_t and size.

void * aligned_malloc(size_t align, size_t size) {
  assert(...);
  if (size < sizeof(max_algin_t)) {
    size = sizeof(max_algin_t);
  }
  ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文