Sign in to follow this  
starfleetrp

Stack Overflow

Recommended Posts

Hi, I am completely confused as to why I am getting a stack overflow. I have located the area/function that is causing the stack overflow, however I am not sure why it would be happening because it actually returns a value and moves on. Here is the main section of my program. Note I added the int test to make the stack over flow sooner than later. Since it was happening in a simple function.
	errorLog = new Log("\\Log.html");
	mmResource = new ResourceManager();
	gemain = new GEMain();

	ResourceManager::GetSingleton().addTextureResource("images\\test.bmp");

	ResourceManager::GetSingleton().add3DSResource("model\\ship hull.3DS");


	//test stuff
	int test[100000];

Now I get my stack overflow when it tries to create the test[100000]. However when I remove add3DSResource it works perfectly. So I can only assume that this is what is creating the problem (rihgt). Now for it to work properly I can only create a test of 7500. This leads me to beleive that this function os causing a stack overflow but I do not see how because arnt objects poped off that stack when they return. I would really appriciate some help with this problem!

Share this post


Link to post
Share on other sites
Don't create arrays of that size on the stack


// bad
int test[100000];

// good
int* test = new int[100000];
// use test
delete [] test;

// better
boost::scoped_array<int> test(new int[100000]);



Share this post


Link to post
Share on other sites

Yeah, your little "Test" takes like 400k out of the stack and that's a bit too much, considering that stack size could be like 1MB by default.

Cheers !

Share this post


Link to post
Share on other sites
EDIT: To make it a bit more clear the stack overflow was still happening in random places later on in the program so I added the int[100000] to make it happend eariler. So I could locate the problem easier.

No, that was not the problem, I just put the array there to make the overflow happen earlier. I used the array so I could make sure that the crate3dsModel was makeing the trouble (because as you can see, if you crusnch the numbers 100,000 - 7500 is like 92,500 * 32 bits (size of int)) so it seems like im loosing alost 400,000 bits or 400 kb from calling that function, and I am not sure why. Before I created the array, to see when the stack would overflow I added a few new functions which started to overflow. So I narrowed down the culprate to the Create3dsModel. So even if I didnt create a large array it would still eventually overflow.

I do not use any arrays in my program instead I use vectors and maps. So pretty much there is only 5 news called before the array is allocated and im sure the problem is in the Create3dsModel.

I will post the code to the create3dsModel

--SOURCE REMOVED

[Edited by - starfleetrp on August 18, 2006 6:46:48 PM]

Share this post


Link to post
Share on other sites
let's see 100000 ints is roughly 390 KB. default stack size if i recall right is 1 MB... should work... does add3DResource create a lot on the stack as well?

EDIT: Wow, 3 posts added as I typed this lol.

Share this post


Link to post
Share on other sites
Ok well as you can see for some reason Create3DSResource is eating up the whole stack because I could create an array of 100000 items no problem but after I called that function it is hard to even create an array 0f 7500. So I am just wondering why the heck it is causing this problem because I dont think im writing to the stack in Create3DSResource.
Repeating from other post: In my actual program the int test[100000] does not exist, it was just to see where the stack was being eaten up.

Share this post


Link to post
Share on other sites
You can increase the default stack size in MSVC++ by adding this segement
to the linker argument section: /STACK:reserve[,commit]. Where commit is the new size in bytes. There are various advantages and disadvantage to this. Check
out this link: clicky

Share this post


Link to post
Share on other sites
Don't do that. That's fixing the symptoms not the actual problem. That should only be an option if you know what is blowing the stack, and are sure its not a bug and you need to do it. Are you using deep recursion in your application? That's the easiest way to blow the stack.

Share this post


Link to post
Share on other sites
I am not sure what you mean by "deep recursion" but here is the singleton class
[source lang = "cpp"]
#pragma once

template<typename T>
class Singleton
{
static T* ms_singleton;
public:
Singleton()
{
assert(!ms_singleton);
//use a cunning trick to get the singleton pointing to the start of the whole, rather than
//the start of the Singleton part of the object
int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
ms_singleton = (T*)((int)this + offset);
}
~Singleton()
{
assert(ms_singleton);
ms_singleton=0;
}
static T& GetSingleton()
{
assert(ms_singleton);
return *ms_singleton;
}
static T* GetSingletonPtr()
{
assert(ms_singleton);
return ms_singleton;
}
};

template <typename T> T* Singleton <T>::ms_singleton = 0;




Share this post


Link to post
Share on other sites
Recursion is when a function calls itself, if it happens too much it will blow the stack. Does your C3dsModel class recurse? You seem to have only posted the header for it.

Share this post


Link to post
Share on other sites
Oops, sorry I just realised that I did not post the code. I do not think that it does, however I will post the code anyways incase I overlooked somethings.

-- CODE REMOVED

[Edited by - starfleetrp on August 18, 2006 6:41:36 PM]

Share this post


Link to post
Share on other sites
ProcessNextChunk is recursing. Set a breakpoint in the top of it and see how deep it goes(how many layers of ProcessNextChunk pile up on the callstack) I'm guessing that's what is blowing the stack.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
*shudders* Wow, like to use singletons much? Normally an indication of poor design and planning. It's basically a global and you're just asking for an issue. But to each their own I guess, plenty of discussions on these forums of all the negative aspects of singletons and the fact their a toss back to C (aka not very OO friendly).

Share this post


Link to post
Share on other sites
Leave it up to an AP to be an asshole and off topic. The program, the log, and a resource manager are perfectly fine candidates for singletons for anyone but the most anal programmers. Not that it matters though, cuz his post isn't about getting feedback on his software architecture.

Share this post


Link to post
Share on other sites
Quote:
Original post by DrEvil
ProcessNextChunk is recursing. Set a breakpoint in the top of it and see how deep it goes(how many layers of ProcessNextChunk pile up on the callstack) I'm guessing that's what is blowing the stack.



It goes two times.

Share this post


Link to post
Share on other sites
Well without the int[7600] anything above 7500 will cause an immediate overflow once I have called the Create3DSResource. Well my program is basically Node->Entity._updateBounds()

The entity contains an
OBB* mOBB

so Entity::_updateBounds calls mOBB->UpdateBounds(orientation,scale,pos) note that this is the function that will overflow with my current setup. However if I do not load the model it does not overflow.

Share this post


Link to post
Share on other sites
You haven't posted that part of the code have you? Might be easiest if you just post the entire thing somewhere.

Share this post


Link to post
Share on other sites

void C3dsModel::ProcessNextChunk(_3DChunk *pPreviousChunk)
{
/* ... */
int buffer[50000] = {0};
/* ... */
case EDITOR_CHUNK:
/* ... */
ProcessNextChunk(mCurrentChunk);
}



So you have recursion with a static array of 50000 itens, might be that. Might, I'm not bothering to check if it's called.

Share this post


Link to post
Share on other sites
Quote:
Original post by vininim
*** Source Snippet Removed ***

So you have recursion with a static array of 50000 itens, might be that. Might, I'm not bothering to check if it's called.
I'd say you're onto something there. That's nearly 200K for a single call of this function alone. It would be best to dynamically allocate that large array, or better yet, simply use a std::vector![cool]

To the OP, I'm not sure you understand that your int test[100000]; takes up space on the stack the moment that the function containing that definition is entered, NOT after the call to add3DResource. It does not matter where in the function you put that declaration as it always takes up space right from the beginning.

Share this post


Link to post
Share on other sites
[quote]Original post by starfleetrp
I am not sure what you mean by "deep recursion" but here is the singleton class

template<typename T>
class Singleton
{
static T* ms_singleton;
public:
Singleton()
{
assert(!ms_singleton);
//use a cunning trick to get the singleton pointing to the start of the whole, rather than
//the start of the Singleton part of the object
int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
ms_singleton = (T*)((int)this + offset);
}
~Singleton()
{
assert(ms_singleton);
ms_singleton=0;
}
static T& GetSingleton()
{
assert(ms_singleton);
return *ms_singleton;
}
static T* GetSingletonPtr()
{
assert(ms_singleton);
return ms_singleton;
}
};

template <typename T> T* Singleton <T>::ms_singleton = 0;



[/quote]

Your singleton class contains a static pointer to some object of type T. This pointer is initialised to 0. The functions GetSingleton() and GetSingletonPtr() return that pointer (or a reference to the object it points to).

In your application the constructor/desctructor of the singleton class is never called (i.e. no instance of the singleton class was created). This way the pointer will remain 0. (Did you really turn on assertions ?)

For more information about creating singletons read here:
http://www.nada.kth.se/cvap/abstracts/cvap246.html
http://www.codeproject.com/cpp/singletonrvs.asp
http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=148&rl=1

Share this post


Link to post
Share on other sites
I didnt really pay attention to the singleton from a tutorial. So I will look into inproving my singleton design by probably replacing it with a better/different one. Thanks for the link.

I will look into the the buffer[50000] or and see if that is causing the problem. These are the only 2 peices of code I used that was not mine (well I did change the 3dsLoader a lot, but the basics like buffer stayed the same) I will try to fix that. Well I guess I also used code from an image loader but hey.

I will post back with my results when I change the buffer arround!

Share this post


Link to post
Share on other sites
Ok instead of re-writing all of my code for a quick check I changed the buffer from 50000 to 1000. It now works perfectly, well not exacly. I no longer would get an immedate buffer overflow. It will happen like after 5 frames, unless I comment out a line of code.

[source lang = "cpp"]
void Entity::_updateBounds()
{
if (!mNode)
{
Log::GetSingleton().addRecord("No Node Bound. Tried to Entity::_updateBounds() on </b>" + mName + "</b>", LOG_ERROR);
return;
}

if (!mModel.isValid())
return;

//mOBB->UpdateBounds(mNode->getDerivedOrientation(), mNode->getDerivedScale(), mNode->getDerivedPosition());
mOBB->UpdateBounds();//(mNode->getDerivedPosition());
}




Now as you can see mOBB->UpdateBounds() will work perfectly but as soon as I pass any parameter over to the function after about it being called a few times (I saw it overflowing after 4 frames). I am not sure why the heck it would be doing this.
mOBB is an OBB class which pretty much just contain the 8 corners of the bounds.
Currently UpdateBounds() does nothing. However as I said it will crash if I pass any parameters to it.

It is declaired like
void OBB::UpdateBounds() OR void OBB::UpdateBounds(Quaternion orientation, const Vector3& scale, const Vector3& position) which crashes
{
//Nothing in here
}

I have fixed the 3dsLoader from causing a buffer overflow, which I should have caught earlier! However this is a problem where I can see nothing wrong.
I know I am being a complete moron... I am sure of it as you haveal ready prooved with the buffer[50000].

I really appriciate all of the help that you are giving me!

[Edited by - starfleetrp on August 18, 2006 6:27:07 PM]

Share this post


Link to post
Share on other sites
never allocate thousands of bytes of memory on the stack, that's just not what it is for.

The stack is for control variables, the heap is for data ... change:

int buffer[50000]

to use the heap and you will be fine.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this