c++ segfault on one platform (MacOSX) but not another (linux) -
i'm getting segfault on macosx ("segmentation fault: 11", in gdb "program received signal sigsegv, segmentation fault"), appearing in destructor in container looped on iterator , memory deleted. i've tried clang++, g++ (both part of llvm) , homebrew g++. segfault appears when iterator incremented first time, gdb message (having compiled clang++)
"0x000000010001196d in std::__1::__tree_node_base<void*>* std::__1::__tree_next<std::__1::__tree_node_base<void*>*>(std::__1::__tree_node_base<void*>*) ()"
when starting program in gdb warnings saying "warning: not open oso archive file".
on cluster linux node, gcc 4.8.1, don't segfault. ideas might wrong , how can avoid segfault on mac (preferably clang)? don't know compilers , such.
edit:
i think found problem, i'd understand still why works on 1 platform not another. here's minimal example:
class word:
#ifndef word_h #define word_h #include <string> #include <map> class word { public: /*** constructor ***/ word(std::string w) : m_word(w) { // add word index map, if it's not in there std::map<std::string, word*>::iterator = index.find(w); if (it == index.end()) { index[w] = this; } } ~word() { index.erase(m_word); } // remove index static void deleteall() { // clear index, delete allocated memory (std::map<std::string, word*>::const_iterator = index.begin(); != index.end(); ++it) { delete it->second; } } private: std::string m_word; static std::map<std::string, word*> index; // index holding words initialized }; #endif
wordhandler class:
#ifndef _wordhandler_h_ #define _wordhandler_h_ #include <string> #include "word.h" class wordhandler { wordhandler() {} ~wordhandler() { word::deleteall(); } // clear memory void wordhandler::newword(const std::string word) { word* w = new word(word); } }; #endif
main program:
#include <iostream> #include "wordhandler.h" int main () { std::cout << "welcome wordhandler. " << std::endl; wordhandler wh; wh.newword("hallon"); wh.newword("karl"); std::cout << "about exit wordhandler after having added 2 new words " << std::endl; return 0; }
so segfault occurs upon exiting of program, when destructor ~wordhandler called. reason found, word destructor: word object erased map, makes deleteall() function weird because map altered while it's being iterated on (some sort of double delete suppose). segfault disappears either removing deleteall completely, or removing word destructor.
so i'm still wondering why segfault doesn't appear on linux g++ gcc 4.8.1. (also, guess off topic, i'm wondering programming – proper way treat index erasing/memory deletion in code?)
edit 2:
i don't think duplicate of vector.erase(iterator) causes bad memory access, because original question had why segfault on 1 platform , not another. it's possible other question explains segfault per se (not sure how around problem... perhaps removing word destructor , calling erase deleteall() rather "delete"? destructor makes sense me though...), if it's bug in code why isn't picked gcc g++?
this problem:
~word() { index.erase(m_word); } // remove index static void deleteall() { // clear index, delete allocated memory (std::map<std::string, word*>::const_iterator = index.begin(); != index.end(); ++it) { delete it->second; } }
delete it->second
invokes ~word
erases map that iterating over. invalidates active iterator, leading undefined behaviour. because ub, fact works on 1 platform not luck (or lack thereof).
to fix this, can either make copy of index
, iterate on that, consider different design doesn't mutate index delete it, or use fact erase
returns next valid iterator make loop safe (which means hoisting erase
deleteall
).
Comments
Post a Comment