Snaipe / libcsptr

Smart pointers for the (GNU) C programming language
https://snai.pe/c/c-smart-pointers/
MIT License
1.57k stars 143 forks source link

How to understand get_meta #20

Closed dzwduan closed 2 years ago

dzwduan commented 2 years ago
size_t* size = (size_t *)ptr - 1;
return (s_meta *)((char *)size - *size);

why first -1, and (char)size - size means what?

Snaipe commented 2 years ago

Allocated smart pointers have this memory representation (assuming a 64-bit system):

|============================================== ... =======|
| metadata              | size          | user data        |
| "size" bytes          | 8 bytes       | variable size    |
|============================================== ... =======|

Initially, ptr points to the start of the user data:

|============================================== ... =======|
| metadata              | size          | user data        |
| "size" bytes          | 8 bytes       | variable size    |
|============================================== ... =======|
                                        ^
                                        `--- ptr

(size_t *)ptr - 1 casts ptr to a size_t pointer, and then subtracts 1 * sizeof (size_t) from the pointer value (which means subtracting 8), which puts size at the start of the size area:

|============================================== ... =======|
| metadata              | size          | user data        |
| "size" bytes          | 8 bytes       | variable size    |
|============================================== ... =======|
                        ^               ^
                        `--- size       `--- ptr

Finally, ((char *)size - *size) does the exact same thing, it casts size to a (char *) then subtracts *size * sizeof (char) (which ends up just subtracting *size from the pointer):

|============================================== ... =======|
| metadata              | size          | user data        |
| "size" bytes          | 8 bytes       | variable size    |
|============================================== ... =======|
^                       ^               ^
`--- metadata           `--- size       `--- ptr

The result is a pointer to the metadata area, which is then returned.

dzwduan commented 2 years ago

excellent!