When I try to run my program( which is a test entity system for anyone who's wondering ), I get a Stack Overflow error, and I cannot find the source of this error.

Here is my code:

baseentity.h:

#ifndef BASEENTITY_H
#define BASEENTITY_H

#include <vector>

#define DECLARE_CLASS( className ) public: virtual char const *_GetClassName( ) { return #className; }

class BaseEntity{
	DECLARE_CLASS( BaseEntity )
private:
	typedef enum{
		eTouch,
		eCollide,
		eSpawn
	} m_eEvents;
	int m_nID;
	static int sm_nCount;
public:
	static std::vector<BaseEntity> sm_vEntities;

	BaseEntity( );
	~BaseEntity( );

	virtual void OnTouch( );
	virtual void OnCollide( );
	virtual void OnSpawn( );
	virtual void FireEvent( int nEvent );
};

#endif //BASEENTITY_H

baseentity.cpp:

#include <vector>
#include <iostream>
#include "baseentity.h"

std::vector<BaseEntity> BaseEntity::sm_vEntities = std::vector<BaseEntity>(100000);
int BaseEntity::sm_nCount = 1;

BaseEntity::BaseEntity( )
:m_nID( sm_nCount )
{
	sm_vEntities.push_back( *this );
	sm_nCount++;
}

BaseEntity::~BaseEntity( )
{
	sm_vEntities.erase( sm_vEntities.begin( ) + m_nID );
}

void BaseEntity::FireEvent(int nEvent)
{
	switch( nEvent )
	{
	case eSpawn:
		OnSpawn( );
	case eCollide:
		OnCollide( );
	case eTouch:
		OnTouch( );
	}
}

void BaseEntity::OnCollide( )
{
}

void BaseEntity::OnTouch( )
{
	std::cout << _GetClassName( ) << "::OnTouch( ): This class does not have a OnTouch function.\n";
}

void BaseEntity::OnSpawn( )
{
	std::cout << _GetClassName( ) << "::OnSpawn( ): This class does not have a OnSpawn function.\n";
}

main.cpp:

#include <iostream>
#include <string>
#include "baseentity.h"

//not my function
void split_string(const std::string& src, std::vector<std::string>& dst, char split)
{
    int startPos = 0, endPos = src.find(split);
	while(endPos != std::string::npos)
    {
        dst.push_back(src.substr(startPos, endPos-startPos));
        startPos = endPos + 1;
        endPos = src.find(split, startPos);
    }
}

int main( )
{
	std::string strCommand;
	std::vector<std::string> vInputs;

	while( strCommand != "exit" )
	{
		std::cout << "> ";
		getline( std::cin, strCommand );

		split_string( strCommand, vInputs, ' ' );

		if( vInputs[0] == "spawn" )
		{		
			for( int i = 0; i < BaseEntity::sm_vEntities.size( ); ++i )
			{
				if( BaseEntity::sm_vEntities[i]._GetClassName( ) == vInputs[1] )
				{
					BaseEntity eTemp;
					eTemp.OnSpawn( );
				}
			}
		}

		if( vInputs[0] == "touch" )
		{		
			for( int i = 0; i < BaseEntity::sm_vEntities.size( ); ++i )
			{
				if( BaseEntity::sm_vEntities[i]._GetClassName( ) == vInputs[1] )
				{
					BaseEntity eTemp;
					eTemp.OnTouch( );
				}
			}
		}

		if( vInputs[0] == "collide" )
		{		
			for( int i = 0; i < BaseEntity::sm_vEntities.size( ); ++i )
			{
				if( BaseEntity::sm_vEntities[i]._GetClassName( ) == vInputs[1] )
				{
					BaseEntity eTemp;
					eTemp.OnCollide( );
				}
			}
		}
	}

	std::cin.ignore( 1200, '\n' );
	std::cin.get( );
}

Thank you for your time.

Recommended Answers

All 18 Replies

right now all that I see that might cause stack overflow might be this..

std::vector<BaseEntity> BaseEntity::sm_vEntities = std::vector<BaseEntity>(100000);

baseentity.cpp
In file included from baseentity.cpp:3:
baseentity.h:8: warning: `class BaseEntity' has virtual functions but non-virtual destructor
main.cpp
In file included from main.cpp:3:
baseentity.h:8: warning: `class BaseEntity' has virtual functions but non-virtual destructor
main.cpp: In function `void split_string(const std::string&, std::vector<std::string, std::allocator<std::string> >&, char)':
main.cpp:9: warning: comparison between signed and unsigned integer expressions
main.cpp: In function `int main()':
main.cpp:31: warning: comparison between signed and unsigned integer expressions
main.cpp:43: warning: comparison between signed and unsigned integer expressions
main.cpp:55: warning: comparison between signed and unsigned integer expressions

I have no idea what you are entering to the program. Any hints?

If you have a stack overflow then try to allocate on heap. Use smart
pointers if you can.

I don't enter anything, when I run it, after about 2 seconds, it comes up with that Stack Overflow error.

what does that mean and how do u do it?

what does that mean and how do u do it?

what do you mean? What is stack overflow? Is that what you
are asking?

What is smart pointers?

What is smart pointers?

First, I don't see why you are using #define. That code is not making
it better.

Smart pointers are pointer that are encapsulated in which they
handle the deletion of the object for you, so you don't have to.

In the standard library, they std::auto_ptr, which is ok for now.

Why isn't the #define making it better?

Oh I see your problem. Its in this line :

std::vector<BaseEntity> BaseEntity::sm_vEntities = std::vector<BaseEntity>(100000);

You are creating a lot of BaseEntity , in this case not enough. What you
should do is this :

std::vector<BaseEntity*> BaseEntity::sm_vEntities = std::vector<BaseEntity*>(100000);

And change the code accordingly.

And generally , using #define is not a good idea. It leads to problems.

Why don't you just make a getClassName function inside your baseEntity. Or you can make a struct name providesClassName and inherit from that struct.

Ok thanks, that fixed the Stack Overflow error.
But now I get the Vector Supscript out of Range error, so I put a check in so that it wouldn't try to do anything if the sm_vBaseEntities vector was empty, but it still gave me the error, I also found that it gave me the error no matter what I typed in. Here is the relevant code:

//....
if( BaseEntity::sm_vEntities.size( ) > 0 )
		{
			if( vInputs[0] == "spawn" )
			{		
				for( int i = 0; i < BaseEntity::sm_vEntities.size( ); ++i )
				{
					if( BaseEntity::sm_vEntities[i]->_GetClassName( ) == vInputs[1] )
					{
						BaseEntity eTemp;
						eTemp.OnSpawn( );
					}
				}
			}

			else if( vInputs[0] == "touch" )
			{		
				for( int i = 0; i < BaseEntity::sm_vEntities.size( ); ++i )
				{
					if( BaseEntity::sm_vEntities[i]->_GetClassName( ) == vInputs[1] )
					{
						BaseEntity eTemp;
						eTemp.OnTouch( );
					}
				}
			}

			else if( vInputs[0] == "collide" )
			{		
				for( int i = 0; i < BaseEntity::sm_vEntities.size( ); ++i )
				{
					if( BaseEntity::sm_vEntities[i]->_GetClassName( ) == vInputs[1] )
					{
						BaseEntity eTemp;
						eTemp.OnCollide( );
					}
				}
			}
			else
				std::cout << "Invalid option!\n";
		}
		else
			std::cout << "Nothing to spawn!\n";
//....

Your help has and will be appreciated.

The error is here : if( vInputs[0] == "spawn" ). vInput[0] is null

So does that mean that I have a problem with my split_string function?

So does that mean that I have a problem with my split_string function?

yes

can you give me a sample input and output.

I enter "spawn BaseEntity"(without the quotes) and it gives me the error.

This is my split_string function:

void split_string(const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters = " ")
{
    // Skip delimiters at beginning.
	std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
    // Find first "non-delimiter".
	std::string::size_type pos     = str.find_first_of(delimiters, lastPos);

	while (std::string::npos != pos || std::string::npos != lastPos)
    {
        // Found a token, add it to the vector.
        tokens.push_back(str.substr(lastPos, pos - lastPos));
        // Skip delimiters.  Note the "not_of"
        lastPos = str.find_first_not_of(delimiters, pos);
        // Find next "non-delimiter"
        pos = str.find_first_of(delimiters, lastPos);
    }
}

I fixed that error by having this instead of the split_string function:

std::string strBuf;
		std::stringstream sStream( strCommand );
        while ( sStream >> strBuf )
			vInputs.push_back( strBuf );

But now I get this(im using the same input):

Unhandled exception at 0x00896cf7 in Entity_System.exe: 0xC0000005: Access violation reading location 0x00000000.

Any more help would be appreciated.

I fixed that one two, but now when I enter "spawn BaseEntity" it outputs this 11 times:

BaseEntity::OnSpawn( ): This class does not have a OnSpawn function.

Any more help would be appreciated.

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.