Deukalion
Deukalion

Reputation: 2655

How do I delete pointer to (struct/object) without destroying pointers inside (struct/object)?

If I have a pointer to a struct/object, and that struct/object contains two other pointers to other objects and I want to delete the "object that contains the two pointers without destroying the pointers it holds" - how do I do that?

Pointer to Object A (Contains Pointer to Object B, Contains Pointer to Object C). Delete Object A Pointer to Object A is deleted, Pointer to Object B / C does still exists.

Is there something that I have to do to make this work?

UPDATE

It's for a game project, I hope this explains it. Right now, I have some "problems" even putting the two pointers to B, C inside the first Struct (A)

struct Player
{
    char * Name;
    Weapon* PlayerWeapon;
    Armor* PlayerArmor;
};

struct Weapon
{
    char * Name;
    int Damage;
};

struct Armor
{
    char * Name;
    int Resistance;
};

And this somehow doesn't work.

Player* CreatePlayer(char * Name, Weapon* weapon, Armor* armor)
{
    Player *pPlayer = new Player;

    pPlayer->Name = name;
    pPlayer->Weapon = weapon;
    pPlayer->Armor = armor;
};

And later when a player "dies", the equipment should not be deleted.

Upvotes: 0

Views: 10410

Answers (5)

Jeeva
Jeeva

Reputation: 4663

The pointers (B & C) contained inside the pointer (A) will not be deleted unless you explicitly do it through your destructor. But you cant use the pointer A to access B & C once you delete the pointer A.

Note: You should be having a copy constructor and = overloaed operator in your class A to avoid shallow copying.

If you want to use the same armor and the weapon for someother player make sure you are not deleting the weapon and armor in your players destructor. Then you can use the same pointers for another player like this.

Weapon* weapon = CreateWeapon();
Armor* armor   = CreateArmor();

Player* player1 = CreatePlayer("Alpha", weapon, armor);
delete player1;

Player* player2 = CreatePlayer("Beta", weapon, armor);
delete player2;

Upvotes: 4

Andrew
Andrew

Reputation: 24846

struct Foo
{
   A *a;
   B *b;
}

Foo *foo = new Foo();
delete foo; //foo now points to garbage. you can't use it
foo = nullptr; //don't use foo!

But you can do so:

Foo *foo new Foo();
//do some stuff with foo
A *a = foo->a;
B *b = foo->b;
delete foo;
foo = nullptr;
// if Foo does not destroy objects pointed by a,b in destructor you can still
//use them through a,b vars
a->doSomeStuff(); //ok
b->doSomeOtherStuff(); //ok

EDIT

In your case armor and weapon are not destroyed. You just lose pointers to them (and get the memeory leak). I suggest you to hold all your armor and weapons in some containers (like std::vector) to keep the pointers

Upvotes: 1

Potatoswatter
Potatoswatter

Reputation: 137810

You should avoid using "naked" pointers. It's better to use a smart pointer class such as shared_ptr or unique_ptr. They take care of new and delete, which are very tricky to get completely right unassisted. These are found in Boost, and shared_ptr is also in the TR1 library (std::tr1::) that probably came with your compiler, or just in plain std:: if your compiler is more recent.

Although you haven't said much about the program, if it's necessary to do something preserve the pointers, it sounds like the object A has the only copy of the pointers to B and C. That is a job for unique_ptr.

In C++11,

struct A_type {
    std::unique_ptr< B_type > B; // Object *owns* B and C
    std::unique_ptr< C_type > C;
};

std::unique_ptr< A_type > A( new A_type );

auto my_B = std::move( A->B ); // Acquire ownership away from object
auto my_C = std::move( A->B );
A.release(); // Delete object and anything it owns (at this point, nothing)

// my_B and my_C are guaranteed to be destroyed at some appropriate time

Upvotes: -1

iammilind
iammilind

Reputation: 69988

Pointer to Object A (Contains Pointer to Object B, Contains Pointer to Object C). Delete Object A Pointer to Object A is deleted, Pointer to Object B / C does still exists?

No, they are in undefined state. Anything can happen to them. May be in your system, you notice that they are existent, but assume it's just an illusion, which is not guaranteed every time.

As soon as, you delete A*, all it's content are available for next dynamic allocation. Possibly they might get allocated to some other object later on. Some system, may 0 out everything which is deleted. Again, anything can happen!

Is there something that I have to do to make this work?

Store B* and C* to other pointers before deleting A*.Then it's perfectly ok, because objects are intact and you have its addresses stored.

Upvotes: 1

TokyoMike
TokyoMike

Reputation: 828

I don't think this is possible without making a copy of a and b first.

Upvotes: 0

Related Questions