I was programming an aligned_malloc
implementation in C++ and mainly use the following code, which can be found in various places on the Interwebs, including 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;
}
I get the *(void**)
in the aligned_malloc
. My misunderstanding is with the cast in the aligned_free
. Since we just want the value and don't have to assign to it why not use
void *ptr = ((void*)((ptrdiff_t)p - sizeof(void*)));
instead of
void *ptr = *((void**)((ptrdiff_t)p - sizeof(void*)));
I thought it was the same but when I tried the first one with an alignment of 64 it gave me an error, but when I tried the second cast the program worked correctly. So what is the difference between the two? I left out the proper C++ casts for the sake of readability.
Let us simplify the code:
int x = 7;
void * p = &x;
void * q = &p;
And now let us draw a diagram:
+---+
x | 7 |
+---+
^
|
+-|-+
p | * |
+---+
^
|
+-|-+
q | * |
+---+
Do you see how p
and q
are not equal? If you have q
, and you want to get to p
, you have to dereference q
. But since a void*
cannot be dereferenced, you have to promise the type system that it will find another pointer after the dereference, hence the cast to void**
before the dereference.
assert(q != p);
assert(*(void**)q == p);
Should be clearer if you replace
void *ptr = *((void**)((ptrdiff_t)p - sizeof(void*)));
with the equivalent
void *ptr = ((void**)((ptrdiff_t)p - sizeof(void*))) [0];
The * is not part of any cast, it is dereferencing a pointer. It's reading data from memory.
On the other hand, you should get a really good book about C++ and look at the functions that are built into the C++ library. That's much more likely to work without problems. Using malloc_aligned means you have two classes of pointers, those allocated by malloc and those allocated by malloc_aligned, and both are incompatible.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.