Hi,

I'm trying to run a program I have coded that has the following setup:

There is a tree containing "player" objects.

Each "player" object has a linked list containing "weapon" objects.

Each "weapon" object has a stack containing "round" objects.

I need to set it up so that of you delete the tree object, all the players within the tree are deleted, which in turn deletes all the weapons in each player's linked list, which in turn deletes all the rounds in each weapons stack in a cascade effect.

The destructor for the tree looks like this:

Tree::~Tree(void)
{
	cout << "Tree Deleted" << endl << endl;
	delete this->root;
}

The destructor for the player class:

Player::~Player(void)
{
	cout << "Player Deleted" << endl << endl;

	delete this->weapons;

	delete this->leftChild;
	delete this->rightChild;
}

The destructor for the linked list class:

LinkedList::~LinkedList(void)
{
	while(!isEmpty())
	{
		delete Delete();
	}

}

The destructor for the weapon class:

Weapon::~Weapon(void)
{
	cout << "Weapon Deleted" << endl << endl;
	delete this->magazine;
}

The destructor for the stack class:

Stack::~Stack(void)
{
	while(this->top != -1)
	{
		delete this->Pop();
	}
}

The destructor for the round class:

Round::~Round(void)
{
	cout << "Round Deleted" << endl << endl;
}

When I run the program, the cascade begins and the output shows:

Tree Deleted

Player Deleted

Weapon Deleted

Round Deleted

Round Deleted

And then BOOM, this error message pops up and the program halts:

Image added as attatchment.


Any ideas on what is going wrong???

James

Dani AI

Generated

This thread shows a textbook ownership/heap-corruption issue. correctly identified heap corruption as the immediate runtime symptom, and later traced the root cause to inserting the same dynamically allocated object into multiple places so it was deleted more than once. The printed destructor messages only prove the destructors were entered — they don’t prove that each delete belonged to a unique owner.

Why the crash happens: most allocators keep metadata alongside allocated blocks. Freeing a block twice or writing past its bounds corrupts that metadata. The allocator detects the corruption on the next allocation/free and aborts with an “invalid pointer” or “corruption” message. A buffer overwrite and a double-delete can produce identical symptoms, so it’s important to confirm which one actually occurred.

Practical fixes and safer patterns:

  • Adopt a clear ownership policy: decide which object owns which resources and enforce it consistently.
  • Prefer RAII and standard containers. Store owned objects with smart pointers (or by value) instead of raw new/delete. For exclusive ownership use std::unique_ptr; for shared ownership use std::shared_ptr; use std::weak_ptr for non-owning back-references.
  • Prevent accidental shallow copies of raw-pointer owners by deleting or implementing copy/move operations (Rule of Three/Five).
    Example (modern C++ style):
    struct Player {
      std::vector<std::unique_ptr<Weapon>> weapons;
      Player(const Player&) = delete;
      Player& operator=(const Player&) = delete;
    };

Debugging checklist:

  • Run AddressSanitizer (-fsanitize=address -g) or Valgrind to find double frees / invalid writes.
  • In Visual Studio enable CRT heap checks / break on allocation/free to catch the exact site.
  • Verify container insert/remove functions actually create or transfer ownership (don’t store the same pointer multiple times).
  • If sharing is intended, make that explicit with shared_ptr; if not, clone or construct a fresh object for each container entry.

These steps remove ambiguity between “buffer overflow” and “double delete” and provide robust ways to prevent future crashes.

Recommended Answers

All 7 Replies

You wrote past the end (or beginning) of your dynamic memory and corrupted any bookkeeping data required by the heap manager.

You wrote past the end (or beginning) of your dynamic memory and corrupted any bookkeeping data required by the heap manager.

Yeah... I don't know what that means. Any ideas on how I could not do that? lol

It means buffer overflow. Check your pointers and verify your indexes.

It means buffer overflow. Check your pointers and verify your indexes.

Ah ok that makes sense lol I'll have a check and post back.

It means buffer overflow. Check your pointers and verify your indexes.

I've had a check through and can't seem to find the problem.

All the pointers appear to be correct and I'm not sure how to verify indexes.

Can you offer any suggestions on action to take?

Post the code here?? Like the entire thing.. or the .cpp file or both.

Post the code here?? Like the entire thing.. or the .cpp file or both.

I have now solved the problem, when I was adding pointers to objects to the various data structures, I was actually passing them a pointer to the SAME object!

What I had done was similar to this:

Class* name = new Class;

Structure->insert(name);
Structure->insert(name);
Structure->insert(name);

Thinking that each time I added it to the structure I was passing it a new instance of Class.

Turns out I was wrong, and when I deleted one, I was deleting the same pointer from every location in every structure.

Rookie mistake I suppose, you live and learn!

commented: Grats for finding the problem. +25
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.