When using member-function-pointers I noticed that they have a size of 8Bytes each. However when I ask the compiler it says it is only 4Bytes. Having a couple of objects in you program which have member-function-pointers and are created dynamically with new will allways crash your program.
Please refer to the following source-code and documentation:
#include <StdIO.h> #include <Reg164ci.h> /* A simple external object */ class cCalculator { public: int calculate(); }; int cCalculator::calculate(){ return 27; } /* The description of the member-function-pointer */ typedef int (cCalculator::*fptr)(); /* An object with an array of such member-function-pointers which is able to call these functions by an index. */ class cAnObject { public: cAnObject(); ~cAnObject(); fptr fptr_array[2]; // 2 x 8 bytes = 16 bytes (see watchwindow) int member1; // 2 bytes int member2; // 2 bytes // -------------------------------------- // total: 20bytes = 0x14bytes }; /* The constructor */ cAnObject::cAnObject() { member1 = 1; member1 = 2; } /* The destructor */ cAnObject::~cAnObject() { member1 = 0; member1 = 0; } int main (void) { // now we have the external object cCalculator calc1; cCalculator calc2; // and a couple of objects containing some function pointes cAnObject test1; cAnObject test2; cAnObject test3; fptr memberfunction = &(cCalculator::calculate); test1.fptr_array[0] = memberfunction; // here we get the size of our objects (see watch window) volatile unsigned long object_addr1 = (unsigned long) &test1; volatile unsigned long object_addr2 = (unsigned long) &test2; volatile unsigned long object_sizeA = object_addr2 - object_addr1; volatile unsigned long object_sizeB = sizeof( test1 ); //... // please notice that the static objects have a distance // which is different from its size ? why? // count the bytes and you see the sizeof() is wrong !! // now we simply create the dynamic object (with the wrong size), why ? compiler ? // which here leads to an -access violation-, due to // the wrong calculated size of the function pointers cAnObject * p_test4; p_test4 = new cAnObject; // and set the function p_test4->fptr_array[0] = memberfunction; // calc the size volatile unsigned long objectSize4 = sizeof( (*p_test4) ); // ---- // now the function call itself cCalculator * p_calc; // here we select our target object p_calc = &calc1; // do the static object call by an index == 0 fptr p_fct1 = test1.fptr_array[0]; int x = ( (p_calc)->*( p_fct1 ))( ); // now use the other object p_calc = &calc2; // do the dynamic object call by an index == 0 fptr p_fct4 = p_test4->fptr_array[0]; int y = ( (p_calc)->*( p_fct4 ))( ); // if there is any time please notice that there is a second bug: // try to remove the line "fptr p_fct4 = ..." // and put it into one line like " int y = ( (p_calc)->*( p_test4->fptr_array[0] ))( ); " // and your whole program will crash ! // just print the result printf("%d = %d \r", x, y ); while (1); }
You you continue to claim "So this basically doesn't matter if you have static objects. But creating them dynamically causes errors due to the wrong internal sizeof."
If the compiler does not use the same offset when doing array[1] or p0[1] or *(p0+1) it really doesn't matter if you have static or dynamic objects. The compiler would not be able to produce correct code for static arrays either.
The question here is still: Have you produced a complete set of figures from the compiler, i.e. without gleaning info from the debugger windows?
Well I recived the variable-data from the watch-window, which includes (size_obj1 >> 0xC, size_array >> 0x18, >> p0 = 0x10fac, >> p1 = 0x10fc0 ).
Is this ok?
@Hans-Bernhard Broeker:
While reading this post I can say you are right, I claimed a couple of things which aren't backed up correctly. After hours of searching for the failure in our program I thought to have a rough understanding of what is going on, so I took the assumptions from experience what might be wrong. But I also noticed there is a missbehaviour of the compiler/linker/debugger or what else. So I proposed the code example from above. Which obviously didn't bring it to the point.
Finally I support the post: If the distance between two objects in an array is 12 bytes (0x0c) but the distance when stepping a pointer is 20 bytes (0x14) then the compiler is most definitely broken! as this is actually true, what can be seen in the testresults1/2.
Probably there is time and you can copy and paste the code from above and follow the idea for yourself. I think its worth trying it.
Thanks.