I was looking for a way to access the vtable directly through a pointer and came across this post: http://www.codeproject.com/Tips/90875/Displaying-vtable-when-debugging
It works fine and I can invoke functions through the vtable entries. But I'm having trouble understanding this line of deo:
void (**vt)() = *(void (***)())ptr;
ptr
is a pointer to an object. How can I decipher this line and how does vt
get the vtable address?
Thank you.
void (**vt)()
vt is a pointer to a pointer to some function. This function returns void and takes no parameters.
void (***)()
means a pointer to pointer to pointer to such a function (ie. one pointer level more than above).
First, you´re casting ptr to such a three-level-pointer-to-function.
Then, you get the thing it points to (with the single
*
), that is a two-level-pointer-to-function, ie. the same type a the variable vt. That means you can assign it to vt, and that´s exatcly what this line does.And why?
A single function pointer to a void-no-param-function can be stored in such a variable x:
void(*x)()
. And not exactly related, if you want to pass some array to a function, you´re passing a pointer. Ie. it´s enough to store the array address in a pointer to access the whole array (if the length is known).That means
void(**vt)()
can store (the address of) an array of function pointers.The vtable is nothing else, just an array of function pointers.
If you have a class Car with some variables like color and a vtable, and it uses eg. 200 byte per object. A pointer to a car is like a pointer to a 200-byte array, and if you access color in the code, the compiler looks up that color is at eg. byte 133 and generates an access to it.
Where the vtable is within this object is implementation defined, but often at the beginning. If you have a pointer to a car, it´s a pointer to a array of 200 byte, separated into some fucntion pointers first and some other data after them ...
=> The vtable, ie. an array of function pointers, starts at the start address of the car.
=> If you cast a car pointer to a pointer to vtable, ie. pointer to "function pointer array", ie. pointer to "pointer to pointer to function" and deference that, you have the vtable array.