Board index » Visual Studio » __vfptr is null

__vfptr is null

Visual Studio228
Hello



I am working on an MDI application. The application's main toolbar

has 4 buttons on it (Lets say A, B, C and D). There is a tab control on

the MainFrame. It has many tabs on it. However, depending on which of

the 4 buttons above has been pressed, only 2 tabs are visible at a

time.



After the application starts, if I click on button C, then I see two

visible tabs. When I click on the right most tab, a window (of type

CMDIChildWnd-derived class) is created. This window has a splitter on

it. It has a data member of type CSplitterWnd.



Everything works fine until I did not click button D.



Once I click button D and do some specific operations and then if I

click on button C - I again see two visible tabs. However, clicking

on rightmost tab thereafter results in an assert. The assert comes

because the __vfPtr member of CSplitterWnd data member is null.



Any idea why this would be happening?



Thanks and regards

Amit Dedhia


-
 

Re:__vfptr is null

This smells strongly of memory damage. The _vptr is the first pointer-sized object in a

structure, so if you accidentally overwrite the structure, you can clobber it. One of the

easiest ways of clobbering a _vptr is something like



class A {

public:

virtual sometype somefunction(...args...);

A() { ::ZeroMemory(this, sizeof(A)); }

};



because 'this' points to a struct that is really implemented under what you see as if it

were



class A {

really_hidden_by_implementation:

VTABLE * _vptr;

public:

A() { ::ZeroMemory(this, sizeof(A)); }

};



where internally we have also the code



_vptr[0] = somefunction;



set at application startup. The code generated by the compiler for

A->somefunction(...actual args...);

is

(A->_vptr[0])(...actual args...);



but you get all the type checking, overload resolution, etc. [so I've greatly simplified

what is going on). So note that if _vptr is accidentally overwritten, either by the

::ZeroMemory shown here, or by some buffer overrun on the block of memory that just

accidentally precedes the allocation of the instances of class A (whether it is in the

heap or on the stack) you will get the error, even if the A pointer remains valid.



OK, that said, there are some techniques that can be used to detect this.



Probably the simplest one is to download and install the Application Verifier from

Microsoft and configure it to detect memory overruns. Another is to do something reallyl

ugly, such as



typedef struct { FARPROC * vptr; } VPTR_CHECK;

#define CHECK_VPTR(A) ASSERT( ((VPTR_CHECK *)A)->vptr != NULL)



you could sprinkle these around liberally in your code, which requires all sorts of ugly

hacks to get the pointer available. Such a technique could be considred a last resort.



Check all your attempts to write arrays of objects to make sure you aren't clobbering

something important with a buffer overrun. Your damage is almost certainly in that set of

"specific operations" you do when button D is clicked.

joe



On 29 Aug 2006 14:04:38 -0700, amitdedhia@yahoo.com wrote:



Quote
Hello



I am working on an MDI application. The application's main toolbar

has 4 buttons on it (Lets say A, B, C and D). There is a tab control on

the MainFrame. It has many tabs on it. However, depending on which of

the 4 buttons above has been pressed, only 2 tabs are visible at a

time.



After the application starts, if I click on button C, then I see two

visible tabs. When I click on the right most tab, a window (of type

CMDIChildWnd-derived class) is created. This window has a splitter on

it. It has a data member of type CSplitterWnd.



Everything works fine until I did not click button D.



Once I click button D and do some specific operations and then if I

click on button C - I again see two visible tabs. However, clicking

on rightmost tab thereafter results in an assert. The assert comes

because the __vfPtr member of CSplitterWnd data member is null.



Any idea why this would be happening?



Thanks and regards

Amit Dedhia

Joseph M. Newcomer [MVP]

email: newcomer@flounder.com

Web: www.flounder.com">www.flounder.com

MVP Tips: www.flounder.com/mvp_tips.htm">www.flounder.com/mvp_tips.htm

-

Re:__vfptr is null



<amitdedhia@yahoo.com>wrote in message

Quote
Hello



I am working on an MDI application. The application's main toolbar

has 4 buttons on it (Lets say A, B, C and D). There is a tab control on

the MainFrame. It has many tabs on it. However, depending on which of

the 4 buttons above has been pressed, only 2 tabs are visible at a

time.



After the application starts, if I click on button C, then I see two

visible tabs. When I click on the right most tab, a window (of type

CMDIChildWnd-derived class) is created. This window has a splitter on

it. It has a data member of type CSplitterWnd.



Everything works fine until I did not click button D.



Once I click button D and do some specific operations and then if I

click on button C - I again see two visible tabs. However, clicking

on rightmost tab thereafter results in an assert. The assert comes

because the __vfPtr member of CSplitterWnd data member is null.



Any idea why this would be happening?



Most likely a buffer overflow, or else using an object pointer as if it were

a plain-old-data pointer. For example, you can't memset(obj, 0, sizeof

*obj) safely on an object that has virtual member functions.



Quote


Thanks and regards

Amit Dedhia







-