void*和*(void**)之间有什么区别?

tot*_*oad 5 c++ pointers

aligned_malloc用C++ 编写了一个实现,主要使用下面的代码,可以在Interwebs的各个地方找到,包括SO:

void * aligned_malloc(size_t size, int align) {
    if (align < 0) {
        return NULL;
    }

    void *ptr;
    void *p = malloc(size + align - 1 + sizeof(void*));

    if (p != NULL) {
        ptr = (void*) (((ptrdiff_t)p + sizeof(void*) + align -1) & ~(align-1));
        *((void**)((ptrdiff_t)ptr - sizeof(void*))) = p;
        return ptr;
    }
    return NULL;
}

void aligned_free(void *p) {
    void *ptr = *((void**)((ptrdiff_t)p - sizeof(void*)));
    free(ptr);
    return;
}
Run Code Online (Sandbox Code Playgroud)

我明白*(void**)aligned_malloc.我的误会是与演员在一起aligned_free.因为我们只想要价值而不必分配它为什么不使用

void *ptr = ((void*)((ptrdiff_t)p - sizeof(void*)));
Run Code Online (Sandbox Code Playgroud)

代替

void *ptr = *((void**)((ptrdiff_t)p - sizeof(void*)));
Run Code Online (Sandbox Code Playgroud)

我认为它是相同的,但当我尝试第一个对齐64时,它给了我一个错误,但当我尝试第二次演员时,程序正常工作.那两者有什么区别?为了便于阅读,我遗漏了适当的C++演员.

fre*_*low 5

让我们简化代码:

int x = 7;
void * p = &x;
void * q = &p;
Run Code Online (Sandbox Code Playgroud)

现在让我们绘制一个图表:

  +---+
x | 7 |
  +---+
    ^ 
    |
  +-|-+
p | * |
  +---+
    ^ 
    |
  +-|-+
q | * |
  +---+
Run Code Online (Sandbox Code Playgroud)

你看到如何pq不平等?如果你有q,并且你想要p,你必须取消引用q.但由于a void*不能被解除引用,你必须向类型系统承诺它会在取消引用后找到另一个指针,因此void**在取消引用之前会转换为.

assert(q != p);
assert(*(void**)q == p);
Run Code Online (Sandbox Code Playgroud)