Jump to content
  • Advertisement
Sign in to follow this  
Misantes

c++ segmentation fault

This topic is 1346 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

Hey all, 

Recognizing that this is a difficult request, I need some help pinpointing where I'm causing this segmentation fault. I have an EntityManager that creates an instance of a spell class. If I add a second instance of the spell class it segfaults on start-up (it works fine with the single instance though).

 

If it's not too vague a question, is there a common reason why adding a second instance of a class would cause a segfault? To the best of my knowledge there are no mishandled pointers. The only ones that exist in game are in the spell class, when it makes new particles, though they are deleted in the destructor. It's far too much code to post here, and I wouldn't know where to parse it down to make it fit as I'm not certain what code is causing the problem, but you're welcome to browse it here. Again, it's the entityManager and Spell classes that seem to be the problem.

 

Valgrind is acting up on my system, and I have little experience using GDB on its own, so I'm in a bit of a lurch. It's not a giant problem at the moment, as I don't really need a second instance of the Spell class, but I worry whatever I'm doing wrong will rear its head later when it's much more difficult to fix. 

 

Anyhow, I'm open to any sort of advice, even general debugging suggestions. Also, huge thank you's in advance as this has been plaguing me all week.

Share this post


Link to post
Share on other sites
Advertisement

Ah, thanks for the heads up. It's typically just the one instance, and I wait until the spell is finished before changing its parameters if a new spell is called. I had a small need for a second, simultaneous instance that brought about the segfault. So, it doesn't generally make a new spell for each spell, it's the same instance of it, just with the parameters changed (see the CastFire(), CastBats() etc in Spell()). 

 

But, you're totally right! I tried both shrinking the size of the spell class, and casting it on the heap, and both get rid of the segfault. I think I'll take your advice and try out a redesigned build. I think I also need to read up a bit on the stack/heap details. This is the second time it's bitten me. After the first time, I took a brief glance, but I can see now that I could definitely benefit from a much deeper read into it. I have a feeling my code is likely rather awkwardly built because of a poor understanding of the differences, and where they can/should be utilized.

 

Anyhow, thanks a ton for the help, I appreciate you taking the time to look through the code, I know these segfault questions are probably sometimes easy to just ignore for a lot of reasons, but I'm glad you stopped to help smile.png

 

Cheers and thanks again!

Edited by Misantes

Share this post


Link to post
Share on other sites

You could also modify the default stack size in your compile settings which will allow you to use larger stacks.

 

gcc: --stack=reserve, commit

MSVC: /STACK: reserve,commit

 

reserve is virtual memory size, commit is actual physical size

 

I couldnt find the clang version but it will be similar to gcc to be honest.

 

Be careful of messing with these settings because they are set to be small for a reason, large stack sizes will not detected endless recursion fast.

Edited by NightCreature83

Share this post


Link to post
Share on other sites

You could also modify the default stack size in your compile settings which will allow you to use larger stacks.

 

gcc: --stack=reserve, commit

MSVC: /STACK: reserve,commit

 

reserve is virtual memory size, commit is actual physical size

 

I couldnt find the clang version but it will be similar to gcc to be honest.

 

Be careful of messing with these settings because they are set to be small for a reason, large stack sizes will not detected endless recursion fast.

Ah, I didn't even know that was possible. I'll probably refrain from messing with that for the moment, but that's definitely good to know.

Share this post


Link to post
Share on other sites

A quick follow-up question to anyone who may know. 

 

So, I got a build working, where I cast the instance of the Spell() class on the heap (I think), as it's a bit simpler than moving the entirety of the EntityManager. My question is, if I declare a std::unique_ptr in the header, but then set it later in the functions, will that count as being on the stack or the heap?

 

quick example:

Class EntityManager
{
    private:
        std::unique_ptr<Spell> SpellOne;
}

void EntityManager::LoadSpell()
{
    SpellOne = std::make_unique<Spell>();//heap?
}
void EntityManager::UseSpell(std::unique_ptr<Spell> &SpellIN)
{
  SpellIN->castSpell();
}

Does this still count as the stack since it was initially declared in the header, or does setting the pointer in a function override that, so it now is on the heap? If I had to guess, since it's a: working, and b: a pointer and still dynamically allocated (i'm probably misusing that term), then it is on the heap, but I thought I would double check before running with this.

Edited by Misantes

Share this post


Link to post
Share on other sites

The instance of Spell will be on the heap, the unique_ptr will be on the stack. Think of it like this (simplified code):

template<class T> class unqiue_ptr
{
public:
    explicit unique_ptr(): ptr(new T()) { }
    ~T() { delete T; }
 
private:
    T* ptr;
};

When you call make_unique, it creates and returns an object of type unique_ptr<T> on the stack. The unique_ptr<T> holds a raw pointer which points to the Spell object which is on the heap.

 

Generally speaking, anything you create using 'new' will be on the heap, everything else will be on the stack. The only case this won't necessarily be true  is if you are using placement new which lets you specify the memory for creating the object.

Edited by Xycaleth

Share this post


Link to post
Share on other sites

The instance of Spell will be on the heap, the unique_ptr will be on the stack. Think of it like this (simplified code):

template<class T> class unqiue_ptr
{
public:
    explicit unique_ptr(): ptr(new T()) { }
    ~T() { delete T; }
 
private:
    T* ptr;
};

When you call make_unique, it creates and returns an object of type unique_ptr<T> on the stack. The unique_ptr<T> holds a raw pointer which points to the Spell object which is on the heap.

 

Generally speaking, anything you create using 'new' will be on the heap, everything else will be on the stack. The only case this won't necessarily be true  is if you are using placement new which lets you specify the memory for creating the object.

Ok. I hate to appear dense here but if you're willing to humor me for a moment, to make sure I'm not misunderstanding you, I'd like to ask you to clarify a couple things.

 

So, if the pointer is on the stack, but the Spell object is on the heap, for most intents and purposes, this should work fine for moving the size of the Spell class from the stack to the heap, as the pointer itself is fairly negligible size-wise, right? And, unless I initialize and declare the pointer within a function (which would make a smart pointer not the ideal choice as as it needs to stay in scope for more than one iteration and would be pretty awkward to do that), this is pretty much unavoidable, and not really a problem, right?

 

Is there a reason (excluding complex reasons I'm not likely to ever come across) to avoid doing things this way, or is this perfectly acceptable practice?

 

I think I mostly just needed clarification that initializing the pointer on the stack wouldn't do something weird and create the object there as well. I spent the evening reading about the stack/heap, but some of the details like this were still eluding me. Most of the examples in my references were of raw pointers, and were declared and initialized within functions, so I worried that  adapting it to smart pointers for my program, and making the pointer a class property would do something funny.

 

Anyhow, thanks again for the help, it's genuinely appreciated :)

Share this post


Link to post
Share on other sites


Is there a reason (excluding complex reasons I'm not likely to ever come across) to avoid doing things this way, or is this perfectly acceptable practice?

It's the way the language was designed to be used.  It's not only acceptable, but one of the reasons why C is still useful after half a century and all the alternatives die off after a decade or so.

Share this post


Link to post
Share on other sites

You could also modify the default stack size in your compile settings which will allow you to use larger stacks.

 

gcc: --stack=reserve, commit

MSVC: /STACK: reserve,commit

 

reserve is virtual memory size, commit is actual physical size

 

I couldnt find the clang version but it will be similar to gcc to be honest.

 

Setting the size of the stack is actually a funtion of the linker in all these compiler packages. In CLang look at the "-z" option for controlling the stack.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!