virtual function table ptr stored to file and then again reread

Y

ypjofficial

Hello All,
I am defining a class with one virtual function and storing its first 4
bytes ie. the address of the virtual function table to a file.I am
again rereading the file in the same program and calling the virtual
function.The function gets called nicely but it shows the junk values
for the member variables of the class of which the function is a
member..below is the code

//Program start
#include "iostream.h"
#include "fstream.h"
struct vptrtable
{
void (*fptr)();
};

class one
{
int i;
public:
one(){i = 9;
}
virtual void fun()
{
cout<<"i is "<<i<<"\ninside fun\n";
}
};

int main()
{
one o;
fstream f("c:\\1.txt",ios::eek:ut);
//storing the vptr into the file
f.write((char*)&o,sizeof(int));
f.close();


int p=0;
fstream g("c:\\1.txt",ios::in);
//getting back the fptr from the file
g.read((char*)&p,sizeof(int));

vptrtable * v=(vptrtable*)p;
//calling the function.
v->fptr();
return 1;
}
//Program end
The output is
i is 1769172585
inside fun

i should be 9..but the function is getting called nicely..
what is going wrong here?
If it has to fail then why the function is getting called correctly?

Thanks and Regards,
Yogesh Joshi


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
V

Victor Bazarov

I am defining a class with one virtual function and storing its first
4 bytes ie. the address of the virtual function table to a file.I am
again rereading the file in the same program and calling the virtual
function.The function gets called nicely but it shows the junk values
for the member variables of the class of which the function is a
member..[..]
what is going wrong here?
If it has to fail then why the function is getting called correctly?

Undefined behaviour is just that, undefined. You cannot sensibly expect
anything certain from it.

V
 
F

Frederick Gotham

Ypj posted:
I am defining a class with one virtual function and storing its first 4
bytes ie. the address of the virtual function table to a file.


Platform-specific assumption.

f.write((char*)&o,sizeof(int));


First you say you want 4 bytes, next you say you want sizeof(int) bytes.
 
T

Thomas J. Gritzan

Hello All,
I am defining a class with one virtual function and storing its first 4
bytes ie. the address of the virtual function table to a file.I am
again rereading the file in the same program and calling the virtual
function.The function gets called nicely but it shows the junk values
for the member variables of the class of which the function is a
member..below is the code

Your code invokes undefined behaviour. There is no (portable) way to
write the vtable to disk, using it later. Even if it would be possible,
it is a bad idea, since when you rebuild your programm, the compiler
could relocate the table, so the vtable pointer may become invalid.

[snipped code]
//Program end
The output is
i is 1769172585
inside fun

i should be 9..but the function is getting called nicely..
what is going wrong here?
If it has to fail then why the function is getting called correctly?

The simple explanation: Your code invokes undefined behaviour, it does
what it does.

The offtopic explanation: You created some sort of a copy of the
original object but left out the "int i". The function tries to access
some garbage value in memory.
 
I

Ismail Pazarbasi

Hello All,
I am defining a class with one virtual function and storing its first 4
bytes ie. the address of the virtual function table to a file.

No offence, but I hope you are well aware of what you are trying to do.
I also hope you already know there has been some talks about those who
write pointers to disk and read them back (first thing I remember is
Herb's talks).

Without looking at the piece of code below, I am guessing that you
forgot "this" pointer and read a junk memory, fortunately, somewhere
that does not cause a page fault (i.e. access violation, segfault).

You need correct "this" pointer to play with (super-fragile) vtable
properly. However, those extreme tricks are not reputable as far as
standard is concerned, as standard does not define vtable layout or
internal implementation details. In multiple-inheritance cases, vtable
layout may become extremely complex and even brings experts down their
knees.
I am
again rereading the file in the same program and calling the virtual
function.The function gets called nicely but it shows the junk values
for the member variables of the class of which the function is a
member..below is the code

//Program start
#include "iostream.h"
#include "fstream.h"
struct vptrtable
{
void (*fptr)();
};

class one
{
int i;
public:
one(){i = 9;
}
virtual void fun()
{
cout<<"i is "<<i<<"\ninside fun\n";
}
};

int main()
{
one o;
fstream f("c:\\1.txt",ios::eek:ut);
//storing the vptr into the file
f.write((char*)&o,sizeof(int));
f.close();


int p=0;
fstream g("c:\\1.txt",ios::in);
//getting back the fptr from the file
g.read((char*)&p,sizeof(int));

vptrtable * v=(vptrtable*)p;
//calling the function.
v->fptr();
return 1;
}
//Program end
The output is
i is 1769172585
inside fun

i should be 9..but the function is getting called nicely..
what is going wrong here?
If it has to fail then why the function is getting called correctly?

Thanks and Regards,
Yogesh Joshi

I see no (run-time) polymorphism here. In fact, I think I have
understood what you want, but the term "vtable" is usually used with
polymorphism.

Anyway, one short part of the answer to your question is (IMHO);
you jump to code, but you do not have a correct object and this pointer,
so the "i" is loaded with garbage. "this" pointer is required to find
correct address of member "i" (well, actually for virtual functions as
well) - it's about memory layout of the object.

If you derive a class from "class one" and call "fun" member function
polymorphically, your call will still go to one::fun rather than the
last override - and you will, of course, not haveany member of the class.

This is not portable, not standard, not good, too fragile, too evil (and
you have used it wrong).

Ismail



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
F

Francis Glassborow

Hello All,
I am defining a class with one virtual function and storing its first 4
bytes ie. the address of the virtual function table to a file.I am
again rereading the file in the same program and calling the virtual
function.The function gets called nicely but it shows the junk values
for the member variables of the class of which the function is a
member..below is the code

The real question is why yyou expect your code to work :)
//Program start
#include "iostream.h" Not a standard header
#include "fstream.h"
Not a standard header
struct vptrtable
{
void (*fptr)();
};
What is this for? And what makes you think that there is such a thing as
a virtual function pointer table. VFPT are just an implementation
detail.
class one
{
int i;
public:
one(){i = 9;
}
Please learn to write constructors using constructor initialiser lists:
one(): i(9) {}
virtual void fun()
Note that as a member function this function can only be called using an
object of type one (or via a reference or pointer to such an object
{
cout<<"i is "<<i<<"\ninside fun\n";
}
};

int main()
{
one o;
fstream f("c:\\1.txt",ios::eek:ut);
//storing the vptr into the file
f.write((char*)&o,sizeof(int));
No, all this does is to store the address of o as an array of char.
Whether that is, or is not the address of a vfpt is entirely
implementation dependant. However, much more important is your
assumptions that 1) the address of an object has the same format as the
address of a pointer to a table of function pointers. 2) that the size
of a pointer is the same as the size of an int.
f.close();


int p=0;
fstream g("c:\\1.txt",ios::in);
//getting back the fptr from the file
g.read((char*)&p,sizeof(int));
And here you go again, there is absolutely no requirement in C++ that
the bits of a pointer can be stored in a int lvalue.
vptrtable * v=(vptrtable*)p;
However even if all your other assumptions happen to work for the
implementation you are using all you have done here is to create a
pointer to a nonexistent object of type vptrtable
//calling the function.
v->fptr();
This has so many problems that it is hard to know where to start. As you
do have an object of type vptrtable v is pointing to some arbitrary
storage. It is pure coincidence that that expression seems to call a
member function of one. But as there is no object of type one anywhere,
directly or indirectly, in that expression statement you are deep in
undefined behaviour and are a little lucky that you have actually done
no damage.
return 1;
}
//Program end
The output is
i is 1769172585
inside fun

i should be 9..but the function is getting called nicely..
what is going wrong here?
If it has to fail then why the function is getting called correctly?

Begs the question. It wasn't called correctly so anything can happen
including reformatting your hard drive or causing some other chaos to
your computer.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions:
http://www.spellen.org/youcandoit/projects


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
Y

ypjofficial

Hi All,
Thanks for the debate..

actually i tried this ..because I am learning COM programming and it is
based on the principle that the first 3 entry of the virtual function
table should always be same.So I was just trying to simulate this
behaviour in my own way by storing the virtual function table pointer
to a file and then later on accessing it..

Thanks for all your help..

Thanks and Regards,
Yogesh Joshi


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
I

Ismail Pazarbasi

Hi All,
Thanks for the debate..

actually i tried this ..because I am learning COM programming and it is
based on the principle that the first 3 entry of the virtual function
table should always be same.So I was just trying to simulate this
behaviour in my own way by storing the virtual function table pointer
to a file and then later on accessing it..

Thanks for all your help..

Thanks and Regards,
Yogesh Joshi


"First three entry of the vtable should always be the same", I don't
remember such a rule. Could that actually mean; "all objects in COM world
derive from IUnknown - directly or indirectly -, which has three methods"?

I recommend you to examine the your object's memory layout in your IDE's
"memory" window (with help of "watch" window as well). Unfortunately, your
question is not applicable in general, so bear with Visual C++ (or Studio)
IDE to investigate vendor-specific things (like vtable layout) further.

This is Microsoft specific question and I think people at Microsoft news
groups would help more.

Visual C++: microsoft.public.vc
ATL library (and COM stuff): microsoft.public.vc.atl

Cheers!
Ismail



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
Y

ypjofficial

"First three entry of the vtable should always be the same", I don't
remember such a rule. Could that actually mean; "all objects in COM world
derive from IUnknown - directly or indirectly -, which has three methods"?
Since this is not a topic to be discussed in this forum I will make it
look like typical C++ discussion so that other won't take any
objection..:)
Interface is an abstract class and abstract class is nothing but a
collection of pure virtual function...so internally the compiler
creates an array(i.e table) of pointers to virtual function (VTABLE)
and store the address of the array(vfptr) as a member of the abstract
class..so when you derive any class from this abstract class , it
inherits the vtable also and the compiler stores the addresses of the
overriden function to the vtable of the derived class..The functions
inside the vtable are always accessed by index..
So coming back to specific COM .. " Every interface should inherit from
the IUNKnown" means the first three entries of the vtable must be of
QueryInterface,AddRef and Release...
I recommend you to examine the your object's memory layout in your IDE's
"memory" window (with help of "watch" window as well). Unfortunately, your
question is not applicable in general, so bear with Visual C++ (or Studio)
IDE to investigate vendor-specific things (like vtable layout) further.

This is Microsoft specific question and I think people at Microsoft news
groups would help more..c++.moderated. First time posters: Do this! ]
Yes..I know..thats why I put the problem without using any platform
specific words..

Thanks for the discussion...

Yogesh Joshi


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
M

Marco Manfredini

Ismail said:
"First three entry of the vtable should always be the same", I don't
remember such a rule. Could that actually mean; "all objects in COM
world derive from IUnknown - directly or indirectly -, which has three
methods"?

I recommend you to examine the your object's memory layout in your
IDE's "memory" window (with help of "watch" window as well).

This isn't neccessary at all. COM mandates a specific vtable layout and
calling convention. If one looks at the headers of the Windows SDK
which define the COM Objects of the runtime, one will see that every
interface is defined twice. Once as an abstract class in C++ and then
again as a C struct with a table of function pointers a the first and
only member. The OP should look at these (and the output of MIDL.EXE
which generates the same sort of setup) to learn about the vtables COM
expects.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,815
Latest member
treekmostly22

Latest Threads

Top