i have piece of code runs normally, breaks when add exception handling. beginner , here's code
this code works (for brevity's sake include guards not shown):
in plane.h:
#include "vector.h" //which, point.h, inherits orderedpair.h class plane { public: plane(const std::string &label); plane(const plane &); virtual ~plane(); void insert(const orderedpair &); void label(const std::string & label); std::string label() const {return _label;} protected: std::string _label; bool operator==(const plane &rhs) const {return label() == rhs.label();} bool operator<(const plane & rhs) const {return label() < rhs.label();} };
in plane.cpp
#include <set> plane::plane(const std::string &label) : _label(label) { getuniverse().insert(this); } /*global objects*/ extern std::set<plane *>& getuniverse() { static std::set<plane *>universe; return universe; } extern plane& getdefaultplane() { static plane default("default"); return default; } void printworld() { (auto : getuniverse()) std::cout << (*getuniverse().find(i))->label() << std::endl; }
and in main:
//mingw32 4.9 code::blocks 16.01 windows vista(!!) 64bit -std=c++11 #include <iostream> #include "vector.h" //includes point.h includes orderedpair.h #include "plane.h" using namespace std; namespace { struct initializer {; initializer(); }; } int main() { static initializer init; point a("a", 1, 1); plane p("p"); plane duplicate("default"); printworld(); return 0; } initializer::initializer() { // trigger construction of default plane getdefaultplane(); }
then include exception in plane.h , add following @ top:
class e : public std::exception { const char *msg = nullptr; public: e(const char *m) throw() : msg(m) {} const char *what() const throw() {return msg;} }; const e duplicateobj("object exists!\n");
it compiles , runs, without problem. change constructor of plane in way (to make sure label has not been used before):
plane::plane(const std::string &label) : _label(label) { (auto : getuniverse()) { if ((*getuniverse().find(i))->label() == _label) throw duplicateobj; } getuniverse().insert(this); }
and comment out instantiation of duplicate plane in main (to avoid triggering throw). compiles , runs, no problem.
then wrap object instantiation lines in try/catch block in main:
try { point a("a", 1, 1); plane p("p"); //plane duplicate("default"); } catch (const e& e) { cerr << e.what() << endl; } catch (const exception &e) { cerr << e.what() << endl; }
it compiles crashes following result:
process returned -1073741819 (0xc0000005) execution time : 9.537 s press key continue.
isn't problem of exceptions.
it's problem of pointer , scope.
if i'm not wrong.
your plane constructor insert (getuniverse().insert(this);
) this
pointer in static global set (static std::set<plane *>universe;
in getuniverse()
).
then, use global set in last instruction of main()
(printworld()
).
before introduction of try
/catch
blocks, scope of plane p("p");
object full main()
function; pointer p
valid pointer when call printworld
.
but when write
try { plane p("p"); // end of p scope } // p out of scope; pointer p, in universe, invalid printworld(); // use of invalid pointer p
the scope of p
try
block; so, when call printworld()
out of try
block, universe
contain pointer destroied object.
crash!
p.s.: sorry bad english.
Comments
Post a Comment