|
You are correct. This is a classic example of what goes wrong when you mix low level constructs with high level ones without a well developed understanding of how the high-level constructs are implemented. Every class that has virtual functions has a virtual function table; one table is shared between all instances of that class. It contains pointers to virtual functions (or sometimes adjustor thunks to the virtual functions if multiple inheritance is used). When the constructor of a class with virtual functions is called it initializes a pointer in the instance data to point to the class’s vtable: this is the pointer that's being overwritten. In short, if you use simple structs and classes (no virtual functions or multiple inheritance) the layout of the class is what you would naively expect; if you have a struct or class with high-level constructs such as virtual functions or multiple inheritance the layout of the class as a whole will not be so predictable and will contain the book keeping info needed to implement them.
Steve
|
|
|
|
|
Just to be more precise: the v-table is not in the object itself, but somewhere in the system.
Its leading address is in the object, and part of the object size, as the virtual base table address (if any).
What is erased is not that table itself, but the table address, hence, by invoking a virtual function, you'll try to find the address by seeking the corresponding entry considering the memory "0" to be the table.
The crash is not the function invoke, but the attempt to read an invalid memory page to detect wich function to invoke.
2 bugs found.
> recompile ...
65534 bugs found.
|
|
|
|
|
I think main idea behind virtual functions is they r there only so that derived classes could make use of it.
If u had written
A* a = new B ;
ur code would have worked fine.
I have not refreshed c++ from last 8 months if I am wrong anybody cancorrect me
bye.
|
|
|
|
|
|
I posted before his reply. anyway i will make use of information
|
|
|
|
|
|
u r almost right, I was in my own world
to be honest I had written my suggestion when nobody had presented reply to the original question, but I failed to press submit.
If I was totally wrong I would not have replied.
why waste our time unnecessarily on useless point.
bye(this time really)
|
|
|
|
|
Sometimes when you start a reply you're the first but you take some time to write it and by the time you send it it's out of date; it has happened to me before today.
Steve
|
|
|
|
|
toxcct wrote: man, either you have a problem in your time management, or you didn't refresh your browser :
It's happened to me a few times that I've replied and found someone's replied before me.
Regards,
Nish
|
|
|
|
|
LordsAngel wrote: memset( a, 0, sizeof( A ) );
Why the heck are you doing this ?
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
A plain C habbit maybe ? In C, for initalizing all data members of a struct, it is quite practical to use such mechanism.
Cédric Moonen
Software developer
Charting control
|
|
|
|
|
As a rule in C++, never initialize a struct /class using memset . That's what constructors are for.
Software Zen: delete this;
|
|
|
|
|
There is nothing wrong with initializing a class /struct with memset if you know what you're doing. The basic rule is only use memset on class s/struct s which:
- Don't have any virtual functions.
- Don't have any virtual base class es.
The above two restrictions are also recursive into the classes members. For example a class itself may not have any virtual functions but some its members may and so it is NOT safe to use memset on it.
While you are correct that "that's what constructors are for" there is little doubt that when it is safe to do so it will be more efficient. Most times the efficiency gain will not be worth it but, as always, there will be exceptions.
If you really want to use memset but still want to use have virtual functions you can do so like this:
struct CMyClass_Data
{
CMyClass_Data()
{
memset(this, 0, sizeof(*this));
}
};
class CMyClass : private CMyClass_Data
{
public:
virtual VFun1() { }
virtual VFun2() { }
}
Steve
|
|
|
|
|
While what you say is true, it still skates closer to the edge than I prefer. I use memset to initialize simple buffers and other types of POD (plain old data), and that's about it. I do use this construct, however:
struct MyData {
...
};
MyData data = { 0 }; in preference to memset most of the time. In this case, the compiler will complain if anything in type MyData has a non-trivial constructor, which guarantees at compile time that the operation is safe.
Software Zen: delete this;
|
|
|
|
|
I've got nothing against this technique and use it myself; but it can't achieve exactly the same result as the example I gave. If you want the members that you're ={0} ing to be members of the class with virtual functions this technique can't be used. I reiterate - in general I wouldn't bother with such confusing constructs - but there are exceptions to every rule.
Steve
|
|
|
|
|
Stephen Hewitt wrote: exceptions to every rule
Well, as long as you catch them properly...
Software Zen: delete this;
|
|
|
|
|
Hi,
My client has a MFC appliation (static library), i did a small modification to couple of files(.cpp) in MFC project & i'm required to send the updated version to my client. My project doesn't have dll's, its just an exe application.
I looked around the internet but cannot find straightforward answer, so my
question is
1. What all i need to send? Just send the newly compiled exe?
2. Is there anyother solution?
Thank you
Mohan
|
|
|
|
|
If the modifications reside in the exe only, then you only need to send the exe. If you made modifications in some external files, you need to send those also. In brief, send what you modified only.
Cédric Moonen
Software developer
Charting control
|
|
|
|
|
Someone please guide me how to install a font programatically. I mean is there any API call like InstallFont(LPCTSTR lpFontName);
Regards,
Aljechin
-- modified at 5:49 Friday 23rd June, 2006
|
|
|
|
|
Do you see CreateFont
whitesky
|
|
|
|
|
Rather than creating an already installed font, I think what you are looking for is AddFontResource() .
"The largest fire starts but with the smallest spark." - David Crow
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
If I want to press F1 in a dialog to finish the same task as VK_DOWN, how can I do?
By the way, why my CMyDialog::OnKeyDown() can not accept a key strike since I have called SetFocus() in CMyDialog::OnInitialDialog()?Thanks
|
|
|
|
|
Implement PreTranslateMessage.
|
|
|
|
|
zouchao1112 wrote: ...why my CMyDialog::OnKeyDown() can not accept a key strike since I have called SetFocus() in CMyDialog::OnInitialDialog()?
Is OnInitDialog() returning FALSE ?
"The largest fire starts but with the smallest spark." - David Crow
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
i wish to ask how to save a file to ftp.without using local files?Like example: i click save to save file.After i type the file name and click save button. then the file will save to ftp directly. any pro help tyty
|
|
|
|