Q:

How does deletion of dynamic memory really work?

In main I have two types of objects: Person and Pet. A Person can have a number of Pets. I am creating both types of objects dynamically. 
#include <iostream>
#include <string>
#include <vector>

struct Pet
{
    Pet() { }

    Pet(std::string name, std::string type)
    {
        Name = name;
        Type = type;
        std::cout << Name << " is created" << std::endl;
    }
    ~Pet()
    {
        std::cout << Name << " is destroyed" << std::endl;
    }

    std::string GetName() { return Name; }
    std::string GetType() { return Type; }

    std::string Name;
    std::string Type;
};

struct Person
{
    Person(std::string name)
    {
        Name = name;
        std::cout << Name << " is created" << std::endl;
    }

    ~Person()
    {
        std::cout << Name << " is destroyed" << std::endl;
    }

    void AddPet(Pet& pet)
    {
        Pets.push_back(pet);
    }

    std::string GetPersonsPets()
    {
        if (Pets.size() == 0)
        {
            return Name + " has no pets";
        }
        if (Pets.size() == 1)
        {
            return Name + " has " + Pets[0].GetName() + ",a " + Pets[0].GetType();
        }
    }

    std::string Name;
    std::vector<Pet> Pets;
};

int main()
{
    Person* peter = new Person("Peter");

    Person* alice = new Person("Alice");

    Pet* fluffy = new Pet("Flyffy", "dog");
    peter->AddPet(*fluffy);

    std::vector<Person*> People;
    People.push_back(peter);
    People.push_back(alice);

    int i = 0;
    for (std::vector<Person*>::iterator it = People.begin(); it != People.end();
        it++)
    {
        std::cout << People[i]->GetPersonsPets() << std::endl;
        i++;
    }
    //delete fluffy;
    delete alice;
    delete peter;
}

Everything seems to work as it should, but something interesting happens when it comes to deleting the Pet objects. When I uncomment delete fluffy, fluffy gets deleted by itself right after peter. 
I thought that, since fluffy was created dynamically, it would never be destroyed unless I did that myself?
But the other interesting thing happens when I don't uncomment delete fluffy.  Then it's destructor will be called twice.
How is it possible to destroy something twice?

A:

When you add the pet here:
peter->AddPet(*fluffy);

then *fluffy is the pointer derferenced and here
void Person::AddPet(Pet& pet)
{
Pets.push_back(pet);
}

You store a copy of *fluffy in some container (I suppose it is a std::vector). 
The objects you see getting destroyed are those copies (vector manages its own memory, ie it destroys its elements when the vector is destroyed). You still need to delete the dynamically allocated instances you created in main.
Note that you better didnt use new and delete at all here. Use dynamic memory when you must. And when you do you better use smart pointers rather than raw pointers.
PS Your code exhibits the bad practice of writing getters just because. All the members of Pet and Person are public. Either make the members private or remove the getters. Having both is misleading. Also if you do provide a default constuctor ( Pet() { }) it should initialize the members to meaningful values. The job of a constructor is to construct an object in a valid state. Last but not least you should use the member initializer list for constructors as in
Pet(std::string name, std::string type) : Name(name),Type(type) {}

A:

Pets.push_back(pet); 

creates a copy of pet and stores it inside vector. When vector is destroyed, this copy is destroyed (but the original fluffy allocated with new is still leaked).
When you uncomment delete fluffy;, then you properly destroy both the original object and it's copy.
If you want to track copies of objects created, add user defined copy constructor and copy assignment operator (read up on The Rule of Three).

