您有一个操作系统,它有两个处理内存分配的功能:

void *malloc( int sz ) // allocates a memory block sz bytes long

void free( void *addr ) // frees a memory block starting at addr
                        //  (previously allocated by malloc)

使用这些函数,实现以下两个函数:
void *malloc_aligned( int sz ) // allocates a memory block sz bytes long,
                               //  aligned to an address divisible by 16

void free_aligned( void *addr )  // frees a memory block starting at addr
                                 // (previously allocated by malloc_aligned)

在解决方案中有以下部分:
void * aligned_malloc(size_t size){
     unsigned char *res=malloc(size+16);
     unsigned char offest=16-((long)res%16);

我不明白的是:为什么我们需要使用unsigned char,为什么要使用16-((long)res%16);并实现什么,在这种情况下(long)res的目的是什么?

最佳答案

不能对“void*”执行指针运算,因为void没有大小。
当向指针添加或减去指针时,总是以sizeof(*p)为单位。意思是-如果向int指针添加一个指针,它的值将增加4(因为整数的大小是4)。因此,当您添加到空指针时,它应该按空指针的大小增长。但空虚是没有尺度的。
然而,有些编译器愿意在void *上进行运算,他们把它当作char *来处理。使用这些编译器,您可以实现这些函数而无需强制转换。但这不是标准。
另一点是,并非所有运算符都适用于指针。加法和减法是,乘法、除法和模数不是。所以如果你想测试指针的低位,想知道它是否对齐,你可以把它转换成一个长的。
为什么这么久?假设long和指针一样大,这在Linux中是正确的,但在Windows中不是。正确的类型是uintptr_t。但是,如果你只对低比特感兴趣,那么在铸造时丢失高比特并不重要。所以对int的转换也会起作用。

关于c - 转换地址,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8777345/

10-17 01:37