Thread: Terminate() inside constructor

  1. #1
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446

    Terminate() inside constructor

    I'm writing a reusable class. The constructor (declared explicit) makes several checks on the std::string passed as an argument.
    In case of a malformed string it throws an exception. Several errors are possible and each provides its own throw. The throws are using the standard library objects declared in stdexcept.

    After all checks are done, it then proceeds to fill in some of its data members.

    The whole error checking section is contained inside a try-catch block.
    The catch blocks simply output the error message through std::cerr and then... I call terminate().

    And this is what is worrying me, as this means any constructors for any objects created so far on the code (some of which could be dynamically allocated objects of other types) exit abnormally without their destructors being called. Using my class would mean that during the coding and testing process, a programmer could be faced with innumerous memory leaks.

    How should I approach this? Should I simply throw and expect the class user to set try-catch blocks on their code (If I still want to output the error message I can simply cerr it and rethrow)?

    On the event I want to actually exit on the constructor, how can I output the error message, and terminate the program safely?
    Last edited by Mario F.; 07-13-2006 at 07:36 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Well if you are actually exiting the program, then all the memmory allocated to the program will be returned to the OS. Atleast with recent OS's. In such a case, calling delete on all alocated memmory is more a good stile thing.

    Old OS's (pre Windows 98 I think) actually did have a problem if memmory was not explisidly freed when the program ends.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #3
    Registered User
    Join Date
    Aug 2001
    Posts
    244
    that sounds like a good use for auto_ptr (or was it autoptr?) - anyway its part of the stl.
    it simply wraps a pointer, and deletes the object when the destructor of the autopointer is called.

    note that when a constructor of a class exits due to a throw, all members are destroyed - but the destructor of the class where the ctor failed won't be called.
    so since all members are destroyed, having all pointers to dynamically created objects wrapped by the auto pointer, the memory will be deallocated safely.
    signature under construction

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Ok... maybe I not interpretating correctly what I read about the terminate function...

    Code:
    int main() {
    
    /*... lots of stuff is coded here including allocated objects ... */
    
    LINE 1543: myclass obj("bad string"); //Bang! Constructor throws and catches. Inside the catch
                                               // block, I output the error message and call terminate()
    }
    Will the objects declared before line 1543 call their destructors?
    Last edited by Mario F.; 07-13-2006 at 08:07 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  5. #5
    Registered User
    Join Date
    Aug 2001
    Posts
    244
    well when the program exits, the operating system should clean up all associated memory.
    why the need to call terminate? wouldnt it suffice either to throw some other exception - or return some value - and let the variables go out of scope?

    edit: i doubt that terminate has a chance to clean up anything. by default it calls abort, and that simply kills the process (afaik). thus the destructors won't be called, since the process terminates, before they would be called automatically by going out of scope.
    Last edited by Raven Arkadon; 07-13-2006 at 08:17 PM.
    signature under construction

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    On unhandled exception cases g++ 3.4.2 only outputs a laconic message. I need to hint the coder as to what caused the exception, hence the need to catch the error and std::cerr it.

    However, I see your point... you suggest I rethrow?
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Registered User
    Join Date
    Aug 2001
    Posts
    244
    ya, i would rethrow
    signature under construction

  8. #8
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    If I don't use try...catch on new, and it threw a std::bad_alloc, which totalled my carefully written application, that's my own fault. I wouldn't call Bjarne and complain that he didn't write a handler into the implementation and call abort.

    Come to think of it, you can just throw the error message with the whole package and all the works and let the user handle/print/log it at a convenient time.

    This is my personal opinion, but you're writing a class, not an application. A user might create an application using other classes with numerous dependencies which happens to include your class. Or a server or other critical system device that must handle errors silently and never close. Error handling should be build into the user interface so that the user can decide where, how and when to handle any messages generated by your class.
    Last edited by jafet; 07-14-2006 at 04:01 AM.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  9. #9
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Okies. Thanks everyone.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 03-26-2006, 12:59 AM
  2. How do I override constructor in inheritance?
    By Loduwijk in forum C++ Programming
    Replies: 13
    Last Post: 03-24-2006, 09:36 AM
  3. calling copy constructor from template
    By Ancient Dragon in forum C++ Programming
    Replies: 3
    Last Post: 09-28-2005, 01:54 PM
  4. constructors
    By shrivk in forum C++ Programming
    Replies: 7
    Last Post: 06-24-2005, 09:35 PM
  5. Copy Constructor Help
    By Jubba in forum C++ Programming
    Replies: 2
    Last Post: 11-07-2001, 11:15 AM