Q:

C++ virtual descructors on the virtual table and the type info of the class

I'm always confused about the memory layout of the c++ virtual table.Here is an example code 
i use to study it:
#include <cstdio>
#include <iostream>
using namespace std;
class Point
{
public:
    Point()
    {
        cout<<"Point constructor"<<endl;
    }

    virtual void func_hs()
    {
        cout<<"Point::func_hs"<<endl;
        printf("the address of this --func_hs:%p\n",&Point::func_hs);
    }
    virtual void  func_zzy()
    {
        cout<<"Point::func_zzy"<<endl;
        printf("the address of this --func_zzy:%p\n",&Point::func_zzy);
    }

    void printVt()
    {
        printf("the address of object,this:%p\nthe address of vt:%p\n",
               this,(void*)*(int*)this);
    }
    void callVtFuncs(int num=2)
    {   
        typedef void (*Funp)(void);

        for(int i=0;i<num;i++)
        {
            Funp funp=(Funp)*((int*)*(int*)this+i);
            printf("%p\n",((int*)*(int*)this+i));
            printf("Point::callVtFuncs=>address of this fun:%p\n",funp);
            if(i==2||i==3)
            {
                continue;
            }
            funp();
        }
    }

    void printVirtualFunAddress()
    {
        cout<<endl<<endl;
        printf("func_hs:%p\nfunc_zzy:%p\n",&Point::func_hs,&Point::func_zzy);
    }
    virtual ~Point()
    {
        cout<<"Point destructor"<<endl;
    }
    virtual void  func_zzzy()
    {
        cout<<"Point::func_zzzy"<<endl;
        printf("the address of this --func_zzzy:%p\n",&Point::func_zzzy);
    }
protected:
    float x,y,z;
};

int main(int argc, char *argv[])
{
    Point point;
    point.printVt();
    point.callVtFuncs(5);
    point.printVirtualFunAddress();
    return 0;
}

I put 4 virtual functions on the class,and print out there address information.Here is the outout:
Point constructor
the address of object,this:0xbffff620
the address of vt:0x8048db8

0x8048db8
Point::callVtFuncs=>address of this fun:0x8048914
Point::func_hs
the address of this --func_hs:0x1
0x8048dbc
Point::callVtFuncs=>address of this fun:0x8048966
Point::func_zzy
the address of this --func_zzy:0x5
0x8048dc0
Point::callVtFuncs=>address of this fun:0x8048b0a
0x8048dc4
Point::callVtFuncs=>address of this fun:0x8048b56
0x8048dc8
Point::callVtFuncs=>address of this fun:0x8048b74
Point::func_zzzy
the address of this --func_zzzy:0x11

func_hs:0x1
func_zzy:(nil)
func_zzzy:0x5
Point destructor

and I'm totally don't understand why the last output is 'funz_zzy:(nil)' and 'funz_zzy:0x5'
but the above is 0x5 and 0x11.
Here is some debug information:(linux 32bit)
(gdb) x/16a 0x8048da8
0x8048da8:  0xa7025 0x0 0x0 0x8048dd4 <_ZTI5Point>
0x8048db8 <_ZTV5Point+8>:   0x8048914 <Point::func_hs()>    0x8048966 <Point::func_zzy()>   0x8048b0a <Point::~Point()> 0x8048b56 <Point::~Point()>
0x8048dc8 <_ZTV5Point+24>:  0x8048b74 <Point::func_zzzy()>  0x696f5035  0x746e  0x804a248 <_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3+8>
0x8048dd8 <_ZTI5Point+4>:   0x8048dcc <_ZTS5Point>  0x3b031b01  0x80    0xf

I can't figure out why there are two Point::~Point()? And  is the information at 0x804a248 stand for the type info of the class? 
some other information:
(gdb) x/1a 0x8048dd4
0x8048dd4 <_ZTI5Point>: 0x804a248 <_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3+8>

what is 0x8048dd4 used for?

A:

I'm totally don't understand why the last output is 'funz_zzy:(nil)' and 'funz_zzy:0x5' but the above is 0x5 and 0x11.

This is because in one case you use printf() with multiple arguments, while in others only with one. And since pointer to members seems to be 8 bytes length type you get this extra zeroes. Try this code:
printf("sizeof func:%u\n",sizeof(&main));
printf("sizeof memfunc:%u\n",sizeof(&Point::printVirtualFunAddress));
printf("sizeof virtmemfunc:%u\n",sizeof(&Point::func_zzzy));

for me it prints
sizeof func:4
sizeof memfunc:8
sizeof virtmemfunc:8

I can't figure out why there are two Point::~Point()?

Looks like this is connected with that it's virtual. If you remove virtual keyword then only one destructor is generated. The second one is the same as the first one, but it additionally calls free() function on some data. I didn't figure out what's this for.

And is the information at 0x804a248 stand for the type info of the class?

This should be the structure you get as the result of typeid(Point).

