Question

Lately I have had a constant battle with a function causing a SEGFAULT randomly. After doing some extra work in trying to find out the problem, I have come up with the following:

All code posted via pastebin:

BUILD 1:This is the original code, it causes the following SEGFAULT (given after link) http://pastebin.com/huzcqnDA

SEGFAULT:

#0 6FC657AC libstdc++-6!_ZNKSs4_Rep12_M_is_leakedEv() (Z:\CPP Programming\CodeBlocks\MinGW\bin\libstdc++-6.dll:??)
#1 6FC89FDB libstdc++-6!_ZNSs4_Rep7_M_grabERKSaIcES2_() (Z:\CPP Programming\CodeBlocks\MinGW\bin\libstdc++-6.dll:??)
#2 6FC8C0E7 libstdc++-6!_ZNSsC1ERKSs() (Z:\CPP Programming\CodeBlocks\MinGW\bin\libstdc++-6.dll:??)
#3 0094A470 Carp::Sprite::Sprite(this=0x27fae8, s=...) (Z:/CPP Programming/Carperon/Source/Carp/Engine/StructL2.hpp:28)
#4 00944E98 Carp::Item::_spr(this=0x1277eb80) (Z:/CPP Programming/Carperon/Source/Carp/../Carp/Classes.hpp:59)
#5 00416219 Carp::WinBag::update(this=0x2857f8, o=false) (Z:\CPP Programming\Carperon\Source\Carp\Interface.cpp:60)
#6 00419304 Carp::GameUI::checkUpdate(this=0x2857e4) (Z:\CPP Programming\Carperon\Source\Carp\Interface.cpp:240)
#7 00401B7D Carp::GameApp::loopGame(this=0x2801ac) (Z:\CPP Programming\Carperon\main.cpp:35)
#8 00402145 _fu2041___ZSt4cout() (Z:\CPP Programming\Carperon\Source\Application.cpp:25)
#9 004017A9 main() (Z:\CPP Programming\Carperon\main.cpp:6)

BUILD 2:This is the current build, currently causes a compiler error, which gives me the idea that this might be the cause of the problem. http://pastebin.com/89gCjH5P

Error:

Z:\CPP Programming\Carperon\Source\Carp\Interface.cpp|57|error: no match for 'operator<<' in 'std::operator<< <std::char_traits<char> >((* &(& std::operator<< <std::char_traits<char> >((* &(& std::operator<< <std::char_traits<char> >((* &(& std::operator<< <std::char_traits<char> >((* & std::cout), ((const char*)"Item Info: ")))->std::basic_ostream<_CharT, _Traits>::operator<< <char, std::char_traits<char> >(a)), ((const char*)"\012ItemContainer: ")))->std::basic_ostream<_CharT, _Traits>::operator<< <char, std::char_traits<char> >(((const void*)((Carp::WinBag*)t|

When I call the getter function given in Character, What is actually happening? I am failing to see what the problem is here, and previous Q&As that I have found do not solve the problem, they only cause it to break another random function later on.

The best I can call this situation is a Heisenbug, since this only occurs when I am in DEBUG mode for an unrelated SEGFAULT somewhere else in the program.

The only possible help I have found is using const-correctness with my getters, only to bring the same exact SEGFAULT to the board again (wasting time into compiling).

P.S. My program has static linkage to Ogre3D, which causes me to have an average compiling time of 5 minutes (more than 7 if I change specific headers). So it will take a long time for me to post edits/results.

P.S. Carp::WinBag is the same as Carp::Interface given in the sample code (gave the wrong class name)

Extra Note: I have had this problem occur for 5 days straight on and off. My sanity can only take so much more of this...

SOLUTION: My situation has been caused from my own laziness somewhere else in the code:

ItemPtr temp(new Item(*listItem[1].get()));
temp->spawnDrop(Coord3(fRAND(-1,1),2,fRAND(-1,1)));
dropList.push_back(temp);
temp.reset(new Item(*listItem[2].get()));
temp->spawnDrop(Coord3(fRAND(-1,1),2,fRAND(-1,1)));
dropList.push_back(temp);
temp.reset(new Item(*listItem[3].get()));
temp->spawnDrop(Coord3(fRAND(-1,1),2,fRAND(-1,1)));
dropList.push_back(temp);

With this, I created a pointer to a new object, BUT at the same time caused the old one to be lost (Memory leak anyone?). This caused all the problems I had later in the code, and writing this the RIGHT way will fix it.

I cannot believe that I did this again after such a long time, and worse NOT realize it... For anyone else that is unfortunate enough to assume this works please DON'T. It will cause endless and confusing stress for you :*

Was it helpful?

Solution

Character doesn't make any guarantee that Items has been initialized to a pointer. When you call it, it simply returns a pointer. If that pointer has not been initialized (or has been initialized to a bad memory location), trying to access that pointer may cause a seg fault:

Character c;
Intem* items = c._items();//get uninitialized ptr in c
items[foo];//seg fault (maybe)

Of course, this isn't the only way that you can get a seg-fault in the call.

What is actually happening in your getter call is that you are taking a "this" pointer, applying an offset to the "this" pointer to find the "items" pointer, and returning that value. However, if your "this" pointer is invalid, then you can get a seg fault. So:

Character* c;//not inititialized
c->_items();//seg fault (maybe)

Can cause a seg fault all on its own.

However, seg faults don't always happen: if the pointer location happens to be to good memory you'll not see the seg fault, you'll just continue down into undefined behavior mode.

SO how on earth do you debug these things? Gotta admit, its a pain in the ass. It is one of the primary reasons people dislike C and C++, and I don't think most people here are going to go looking for it for you.

Most compilers in Debug mode will force uninitialized pointers to a value. Sometimes the value is in hexspeak (My favorite being 0xBADF00D). So look at your pointer values. Visual studio initializes pointers to 0xccccccccccccc.

However, the BEST way to avoid this type of problem is to make having uninitialized pointers impossible. Use vectors and references. When you have to use pointers, stick to smart pointers. Use an RAIIdesign patterns with your constructors and destructors. Follow the Rule of 3 (or Rule of 3-5 in c++11). You'll never (ok you'll "rarely") need to look for invalid values because you've made them hard to exist.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top