Archived

This topic is now archived and is closed to further replies.

HELP! std::vector Debug Assertion Failed _BLOCK_TYPE_IS_VALID

This topic is 5605 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, Below is some sample code that causes a Debug Assertion Failed error in VC++6. It's one of those _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) dealies. This is an example of what I'm trying to do. It's a much more simplified version, but still generates the error. The problem is that the vector push_back calls the destructor for newBarrel and BAM I get the above error.
  
#include <vector>
using namespace std;

///////////////////////////////////////////

// CBarrel

class CBarrel
{
public:
	int		m_nNumMonkeys;
	int*	m_pMonkeys;

public:
	CBarrel() : m_nNumMonkeys(0), m_pMonkeys( NULL )	{}
	~CBarrel()											{ Destroy(); }

	bool	Destroy();
};

bool CBarrel::Destroy()
{
	if ( m_pMonkeys )
		delete [] m_pMonkeys;

	return true;
}
///////////////////////////////////////////


///////////////////////////////////////////

// CZoo

class CZoo
{
public:
	std::vector<CBarrel>	m_pBarrelList;

public:	
	CZoo()					{}
	virtual ~CZoo()			{ m_pBarrelList.clear(); }

	void AddMonkeys( int nNumMonkeys );
};

void CZoo::AddMonkeys( int nNumMonkeys )
{
	CBarrel	newBarrel;

	newBarrel.m_nNumMonkeys = nNumMonkeys;
	newBarrel.m_pMonkeys = new int[nNumMonkeys];
	
	m_pBarrelList.push_back( newBarrel );
}

///////////////////////////////////////////

int main(int argc, char* argv[])
{
	CZoo*	pZoo = new CZoo;

	pZoo->AddMonkeys( 3 );
	pZoo->AddMonkeys( 5 );
	pZoo->AddMonkeys( 2 );
	
	delete pZoo;

	return 0;
}
  
What I'm trying to do, in essence, is have a dynamically allocatable array that gets allocated by another object and pushed onto the back of a list of such objects. Then, that object is responsible for clearing the list and deallocating the memory of each object by calling it's destructor (which is done by the m_pMonkeyList.clear() statement). Why do I get this error when I do the push_back? Why is the destructor being called prematurely (if that's indeed what the problem is)? Any help would be appreciated... Thanks, Bogart [edited by - Stoffel on September 12, 2002 2:30:29 PM]

Share this post


Link to post
Share on other sites
I think the problem is because your CBarrel class doesn't have an assignment operator and a copy constructor.

EDIT: As it is now, std::vector has to use the default copy constructor, witch means the data in CBarrel::m_pMonkeys is never copied, just the pointer. Wich means that various barrels will free each others monkeys and such...

[edited by - LNK2001 on September 12, 2002 2:07:48 PM]

Share this post


Link to post
Share on other sites
Yup, that''s the problem. You could fix this by either:
- adding the copy constructor and assignment operator to CBarrel
- make your barrel use a std::vector instead of keeping your own array; the default copy ctor and assignment op will then "do the right thing"

I suggest the second method.

Share this post


Link to post
Share on other sites
Thanks all,

That did the trick. I added a copy constructor and an assignment operator.

I didn't want to use a std::vector for these arrays since they're huge in my real code and didn't want to worry about the overhead of std::vector constantly resizing.

Thanks again for the help!

Bogart

EDIT: Here's what I added to the CBarrel class in case anyone cares

// copy constructor
CBarrel( const CBarrel &barrel ) :
m_nNumMonkeys( barrel.m_nNumMonkeys ),
m_pMonkeys( new int[barrel.m_nNumMonkeys] )
{
memcpy( m_pMonkeys, barrel.m_pMonkeys, sizeof( int ) * barrel.m_nNumMonkeys );
}

// assignment operator
const CBarrel &operator = ( const CBarrel &barrel )
{
m_nNumMonkeys = barrel.m_nNumMonkeys;
m_pMonkeys = new int[m_nNumMonkeys];
memcpy( m_pMonkeys, barrel.m_pMonkeys, sizeof( int ) * barrel.m_nNumMonkeys );
return *this;
}

[edited by - Bogart on September 12, 2002 2:45:39 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Bogart
I didn''t want to use a std::vector for these arrays since they''re huge in my real code and didn''t want to worry about the overhead of std::vector constantly resizing.



Use the reserve member function of std::vector to reserve memory for push_back() operations. std::vector, if used properly, is just as good as a plain array.

Share this post


Link to post
Share on other sites