The virtual destructor has the same purpose as a virtual function. At runtime looking at the type of object referred by a pointer or reference it is decided which destructor to call -- the destructor of the base class or the destructor of the derived class.
For example, suppose B is a base class and D is a class derived from B and suppose both classes have declared their destrcutor as virtual. Suppose a pointer B *ptr is initialized as follows:
B *ptr = new D();
Now the ptr is of type B* but points to an object of D. So when this object is freed or goes out of scope D's destructor will be called since the destructors have been declared as virtual.