Skip to main content

virtual function table pointers and memset

  • Had a break from learning c# by making a new player model, britanny of gold digger.
    Model, basic texture, animation in 3 days (less actually, time also spent rewriting bone spring code (to get tail to work well), like 2 days plus one recovery…

  • combat prototype is done (cough, after a work/ life related pause of 7 months)

    turn based hex combat, 3 stats (rock paper sizzors/ body mind soul) though still needs tweaking, but need to make some contents tools first. have movement,…

  • slowly implementing a hex based combat mode, have player movement (calculation of what movement cost to get to each square, interface for move, interface for changing facing) and player/ opponent take turns

    also lost some time to changing…

  • Nothing that exciting, still a bit to go before seeing game character fight, but the framework for the turnbased combat, and triggering it by walking around in the world, and then generate a hex grid over the current location is slowly…

  • Used up a weeks worth of holiday time from work, but still did not even get started on the combat prototype.
    Took a day to tidy up the prototype code to be more generalise, then another day to refactor the code to run under a state machine…

  • well, there is more i would like to do on the player movement prototype but need to move onto the next prototype, combat.

    did get physics update seperate from the rendering, the animation states being driven by an xml defined state machine…

  • still working on the character movement prototype, adding a few animations and tweaking physics, currently adding push object state, have the jump animations with jump scalled by time the jump button is down, land animation scalled by time in air…

  • have changed to using ogre game engine, and this is after a few weekends of mucking around and making content, with smatterings of code

    some history. got my own 'from scratch' game engine up to runing but was going to be a pain to support…

  • One day to make the model
    (lightwave, drew a front and side profile of a Fred Perry character, 'Gina', from his comic 'Gold Digger', it is rather sexist, but also a lot of fun. converted the tga into a point cloud to have in the modelling…

  • an interesting little exercise that i did back in november, was to make a pac man clone.

    it was good to actually 'finish' something, but a pain in the kahoonas to make something on the pc not using directX (as i already knew how to use…

Submitted by davidcoen on

not that i write code (cough) but was writing something suspiciously big over several days, in vc6, and today stated to use memset in my object constructors (got bored initilising stuff to 0).

was also using virtual functions in some objects, and after a while i stated to wonder where the virtual table pointer for the compiler to know which 'virtual function table' the base object was using, as it would be really impressive if it was outside the object, as each base pointer needs some unique way of knowing _which_ table to use

and now i'm currently having a break, as just steped through some code, and the virtual function table pointer seems to be zeroed by a call to memset(this,0,sizeof(KeyObj))

not happy.

summary, don't use memset in constructors of classes with virtual functions. if i read this before, i now know to pay attention to it.

DSC

Submitted by Daemin on Thu, 24/07/03 - 10:52 PMPermalink

Yeah, tha's one of those big no-no's, to use memset to set all of an object's contents to 0. It's okay to do it in plain old C code because they have no such thing built in, but not in C++.

Generally though an object has a vfpt (Virtual Function Pointer Table) if the class has inherited or has any virtual methods. It will have more than one of these pointers and tables if it has inherited from more than one class containing virtual functions.

Submitted by redwyre on Fri, 25/07/03 - 8:54 PMPermalink

you might be able to do something with an unnamed struct and/or an unnamed union and memset that

Submitted by redwyre on Sat, 26/07/03 - 7:35 AMPermalink

union
{
char dummy;
struct
{
int a,b,c;
float x,y,z;
};
};

hmmmm...

Submitted by Daemin on Sat, 26/07/03 - 7:40 AMPermalink

Why bother when you can jsut explicitly set every value... and you can reserve memset for the larger arrays and such.

Submitted by redwyre on Sat, 26/07/03 - 8:01 AMPermalink

yeah, generally if the initialiser list is too large, it's time to rethink the structure anyway

Submitted by davidcoen on Sat, 26/07/03 - 9:52 AMPermalink

thanks for comments everyone. was just surprised that the vtp didn't behave like malloc base (which i think puts a link list and flag infront of any memory returned...)

good point redwyre about not letting classes get too big (though unnamed struct in class looks evil :) i like evil.

threw out a days worth of codeing just to redesign it tomorrow, and even went back to clean up one of my base classes

//slightly disturbed buy redwyre having a GUID

Submitted by redwyre on Wed, 13/08/03 - 2:18 AMPermalink

yay, throw away that dirty code!

malloc is evil, if you are using it in C++ code I'll have to send some of my ninja's after you(trained in the deadly art of code-fu).

Submitted by Blitz on Wed, 13/08/03 - 4:58 AMPermalink

If i understand you correctly...
It doesn't behave like malloc, because the memory returned by malloc is allocated natively by the operating system. VFP tables are handled at the application level, and memset etc. are handled at the OS layer and so have no knowledge of the app (and vfp table)...
Perhaps a C++ version of memset could be created to handle VFP tables :P
I think thats about right.
CYer, Blitz

Submitted by Daemin on Wed, 13/08/03 - 7:24 AMPermalink

But the number of VFP tables depends on how many objects with virtual function a certain class has in its hierarchy.

Submitted by pragma x on Wed, 13/08/03 - 2:48 PMPermalink

Two Possible Solutions
I'm not entirely sure about this, but you may be able to rely on the fact that (most/all?) compilers will layout the internal fields of the struct/class in the order they are declared. If you memset the area between the first and last declared members (inclusive), you can effectively set the data area of the class. This technique will also have the side-effect of clearing any internal padding between members, which may or may not be desireable.

Note that we don't use 'sizeof' since it returns the memory area *including* any trailing padding (and of course the space occupied by the class' v-table).

Lack of supporting polymorphism aside, this should do the trick.
[code]
// macro shamelessly ripped off from microsoft
#define offsetof(s,m) (size_t)&(((s *)0)->m)

class Foobar
{
int a; // first member
char b;
float c;
double d; // last member
public:
virtual ~(){} // we want a class w/a vtable

static Clear(Foobar* pFoobar)
{
size_t ofsFirst = offsetof(pFoobar,a);
size_t ofsLast = offsetof(pFoobar,d) + sizeof(d);
memset(pFoobar + ofsFirst,0,ofsLast - ofsFirst); }
};

void main()
{
Foobar a;
Foobar::Clear(a);
}
[/code]
Another way would be to override the new operator, which may not be desireable but is by far less of a hack. This works well since the allocation *has* to ocurr before the constructor can run, and before the vtable can even be assigned to the newly allocated slice of memory. Of course, this won't help any statically declared objects that never call 'new'.
[code]
void* operator new(size_t size)
{
void* p = malloc(size);
memset(p,0,size);
return(p);
}

// 'delete' included since some compilers complain when you don't
// implement a matching 'delete' for your overidden 'new'.
void operator delete(void* p)
{
free(p);
}
[/code]

Submitted by redwyre on Wed, 13/08/03 - 8:53 PMPermalink

offsetof is part of the standard () :)

another alternative (just FYI, this is all getting to be quite hackish):

template< class Ty > class ExplicitDefaultCtor
{
proteced:
Ty m_object;
public:
ExplicitDefaultCtor() : Ty() { }
operator Ty& () { return m_object; }
operator const Ty& () const { return m_object; }
};

class Foo { ExplicitDefaultCtor foo; }

actually, I think vc7.0/7.1 calls the default constructor of built in types now, so none of this should be nessisary..

Posted by davidcoen on

not that i write code (cough) but was writing something suspiciously big over several days, in vc6, and today stated to use memset in my object constructors (got bored initilising stuff to 0).

was also using virtual functions in some objects, and after a while i stated to wonder where the virtual table pointer for the compiler to know which 'virtual function table' the base object was using, as it would be really impressive if it was outside the object, as each base pointer needs some unique way of knowing _which_ table to use

and now i'm currently having a break, as just steped through some code, and the virtual function table pointer seems to be zeroed by a call to memset(this,0,sizeof(KeyObj))

not happy.

summary, don't use memset in constructors of classes with virtual functions. if i read this before, i now know to pay attention to it.

DSC


Submitted by Daemin on Thu, 24/07/03 - 10:52 PMPermalink

Yeah, tha's one of those big no-no's, to use memset to set all of an object's contents to 0. It's okay to do it in plain old C code because they have no such thing built in, but not in C++.

Generally though an object has a vfpt (Virtual Function Pointer Table) if the class has inherited or has any virtual methods. It will have more than one of these pointers and tables if it has inherited from more than one class containing virtual functions.

Submitted by redwyre on Fri, 25/07/03 - 8:54 PMPermalink

you might be able to do something with an unnamed struct and/or an unnamed union and memset that

Submitted by redwyre on Sat, 26/07/03 - 7:35 AMPermalink

union
{
char dummy;
struct
{
int a,b,c;
float x,y,z;
};
};

hmmmm...

Submitted by Daemin on Sat, 26/07/03 - 7:40 AMPermalink

Why bother when you can jsut explicitly set every value... and you can reserve memset for the larger arrays and such.

Submitted by redwyre on Sat, 26/07/03 - 8:01 AMPermalink

yeah, generally if the initialiser list is too large, it's time to rethink the structure anyway

Submitted by davidcoen on Sat, 26/07/03 - 9:52 AMPermalink

thanks for comments everyone. was just surprised that the vtp didn't behave like malloc base (which i think puts a link list and flag infront of any memory returned...)

good point redwyre about not letting classes get too big (though unnamed struct in class looks evil :) i like evil.

threw out a days worth of codeing just to redesign it tomorrow, and even went back to clean up one of my base classes

//slightly disturbed buy redwyre having a GUID

Submitted by redwyre on Wed, 13/08/03 - 2:18 AMPermalink

yay, throw away that dirty code!

malloc is evil, if you are using it in C++ code I'll have to send some of my ninja's after you(trained in the deadly art of code-fu).

Submitted by Blitz on Wed, 13/08/03 - 4:58 AMPermalink

If i understand you correctly...
It doesn't behave like malloc, because the memory returned by malloc is allocated natively by the operating system. VFP tables are handled at the application level, and memset etc. are handled at the OS layer and so have no knowledge of the app (and vfp table)...
Perhaps a C++ version of memset could be created to handle VFP tables :P
I think thats about right.
CYer, Blitz

Submitted by Daemin on Wed, 13/08/03 - 7:24 AMPermalink

But the number of VFP tables depends on how many objects with virtual function a certain class has in its hierarchy.

Submitted by pragma x on Wed, 13/08/03 - 2:48 PMPermalink

Two Possible Solutions
I'm not entirely sure about this, but you may be able to rely on the fact that (most/all?) compilers will layout the internal fields of the struct/class in the order they are declared. If you memset the area between the first and last declared members (inclusive), you can effectively set the data area of the class. This technique will also have the side-effect of clearing any internal padding between members, which may or may not be desireable.

Note that we don't use 'sizeof' since it returns the memory area *including* any trailing padding (and of course the space occupied by the class' v-table).

Lack of supporting polymorphism aside, this should do the trick.
[code]
// macro shamelessly ripped off from microsoft
#define offsetof(s,m) (size_t)&(((s *)0)->m)

class Foobar
{
int a; // first member
char b;
float c;
double d; // last member
public:
virtual ~(){} // we want a class w/a vtable

static Clear(Foobar* pFoobar)
{
size_t ofsFirst = offsetof(pFoobar,a);
size_t ofsLast = offsetof(pFoobar,d) + sizeof(d);
memset(pFoobar + ofsFirst,0,ofsLast - ofsFirst); }
};

void main()
{
Foobar a;
Foobar::Clear(a);
}
[/code]
Another way would be to override the new operator, which may not be desireable but is by far less of a hack. This works well since the allocation *has* to ocurr before the constructor can run, and before the vtable can even be assigned to the newly allocated slice of memory. Of course, this won't help any statically declared objects that never call 'new'.
[code]
void* operator new(size_t size)
{
void* p = malloc(size);
memset(p,0,size);
return(p);
}

// 'delete' included since some compilers complain when you don't
// implement a matching 'delete' for your overidden 'new'.
void operator delete(void* p)
{
free(p);
}
[/code]

Submitted by redwyre on Wed, 13/08/03 - 8:53 PMPermalink

offsetof is part of the standard () :)

another alternative (just FYI, this is all getting to be quite hackish):

template< class Ty > class ExplicitDefaultCtor
{
proteced:
Ty m_object;
public:
ExplicitDefaultCtor() : Ty() { }
operator Ty& () { return m_object; }
operator const Ty& () const { return m_object; }
};

class Foo { ExplicitDefaultCtor foo; }

actually, I think vc7.0/7.1 calls the default constructor of built in types now, so none of this should be nessisary..