我刚刚完成了工作面试的一部分测试,有一个问题难住了我,甚至用谷歌作为参考。我想看看StackOverflow的工作人员可以做什么:

memset_16aligned函数需要传递给它一个16字节的对齐指针,否则它将崩溃。 a)如何分配1024字节的内存,并将其对齐到16字节的边界? b)在memset_16aligned执行后释放内存。

{    
   void *mem;
   void *ptr;

   // answer a) here

   memset_16aligned(ptr, 0, 1024);

   // answer b) here    
}

当前回答

也许他们会满足于memalign的知识?正如乔纳森·莱弗勒(Jonathan Leffler)指出的,有两个更新的更可取的函数需要了解。

哦,弗罗林先我一步。但是,如果您阅读了我链接到的手册页,您很可能会理解前面的帖子提供的示例。

其他回答

size =1024;
alignment = 16;
aligned_size = size +(alignment -(size %  alignment));
mem = malloc(aligned_size);
memset_16aligned(mem, 0, 1024);
free(mem);

希望这是一个最简单的实现,让我知道你的意见。

也许他们会满足于memalign的知识?正如乔纳森·莱弗勒(Jonathan Leffler)指出的,有两个更新的更可取的函数需要了解。

哦,弗罗林先我一步。但是,如果您阅读了我链接到的手册页,您很可能会理解前面的帖子提供的示例。

在16字节计数vs 15字节计数的填充前面,为了获得N的对齐,您需要添加的实际数字是max(0,N-M),其中M是内存分配器的自然对齐(两者都是2的幂)。

由于任何分配器的最小内存对齐都是1字节,因此15=max(0,16-1)是一个保守的答案。然而,如果你知道你的内存分配器将给你32位整型对齐的地址(这是相当常见的),你可以使用12作为一个垫。

这对于本例来说并不重要,但对于具有12K RAM的嵌入式系统来说可能很重要,因为其中保存的每个int都很重要。

实现它的最好方法是,如果你真的想保存每一个字节,那么你可以把它作为宏,这样你就可以给它你的本机内存对齐。同样,这可能只对需要保存每个字节的嵌入式系统有用。

在下面的例子中,在大多数系统上,值1对于MEMORY_ALLOCATOR_NATIVE_ALIGNMENT来说是很好的,但是对于我们的32位对齐分配的理论嵌入式系统,以下可以节省一小部分宝贵的内存:

#define MEMORY_ALLOCATOR_NATIVE_ALIGNMENT    4
#define ALIGN_PAD2(N,M) (((N)>(M)) ? ((N)-(M)) : 0)
#define ALIGN_PAD(N) ALIGN_PAD2((N), MEMORY_ALLOCATOR_NATIVE_ALIGNMENT)

你也可以添加一些16字节,然后通过添加指针下面的(16-mod)将原始ptr推到16位对齐:

main(){
void *mem1 = malloc(1024+16);
void *mem = ((char*)mem1)+1; // force misalign ( my computer always aligns)
printf ( " ptr = %p \n ", mem );
void *ptr = ((long)mem+16) & ~ 0x0F;
printf ( " aligned ptr = %p \n ", ptr );

printf (" ptr after adding diff mod %p (same as above ) ", (long)mem1 + (16 -((long)mem1%16)) );


free(mem1);
}

这里有一个“四舍五入”部分的替代方法。不是最出色的编码解决方案,但它完成了工作,这种类型的语法更容易记住(plus将适用于对齐值不是2的幂)。uintptr_t强制转换是必要的,以安抚编译器;指针算术不太喜欢除法或乘法。

void *mem = malloc(1024 + 15);
void *ptr = (void*) ((uintptr_t) mem + 15) / 16 * 16;
memset_16aligned(ptr, 0, 1024);
free(mem);