scholes@spot.Colorado.EDU (Genuine Bud Man) (05/24/91)
Please excuse me if this is a FAQ, or if I am missing something painfully obvious, but destructors don't seem to be called when the user hits ^C in Turbo C++. I developed a class library for giving "sort of" virtual data space. The program requests X amount of mem, and the class tries to satisfy the request first thru main memory, XMS, then disk space. I have alloc, read, write, and free functions. Each class instance may only be manipulating one block of memory at a time, so multiple class instances are running (at least in my stat app). The problem is that when the user types ^C, the destructors are not called, and if the memory is in XMS or disk, then the XMS is not freed, or the swap file not deleted. I could easily write a ^C handler, and intercept ^C, but how would the handler know who to call, since the class instances are auto vars of another function? I could have the handler ignore ^C, but I would like to have that functionality. I am new to C++, so there may be something staring me in the face here, but I am lost as to what to do. I guess the same basic problem would exist in C, so how would it be handled? Global variables? Thanx in advance, Marty
ahodgson@athena.mit.edu (Antony Hodgson) (05/24/91)
In article <1991May24.045847.24401@colorado.edu> scholes@spot.Colorado.EDU (Genuine Bud Man) writes: > Please excuse me if this is a FAQ, or if I am missing something >painfully obvious, but destructors don't seem to be called when >the user hits ^C in Turbo C++. .. stuff deleted >The problem is that when the user types ^C, the destructors are not called, >and if the memory is in XMS or disk, then the XMS is not freed, or the >swap file not deleted. > I could easily write a ^C handler, and intercept ^C, but how >would the handler know who to call, since the class instances are >auto vars of another function? If ^C does the equivalent of exit(), then only global variable destructors are called. If it does the equivalent of abort(), no destructors are ever called. Borland C++ does have the atexit pragma, but since you can't pass parameters to it, you must have global variables available to tell you what swap files exist or what XMS blocks are not yet freed. Tony Hodgson ahodgson@hstbme.mit.edu
steve@taumet.com (Stephen Clamage) (05/25/91)
scholes@spot.Colorado.EDU (Genuine Bud Man) writes: > Please excuse me if this is a FAQ, or if I am missing something >painfully obvious, but destructors don't seem to be called when >the user hits ^C in Turbo C++. Until exceptions are part of the language, this is the problem of interrupted control flow. If you have a local object and suddenly jump out of the function where it was constructed (as from an interrupt or longjmp) the destructor will not be called, and there is no way to ensure that it will be called. Destructors for static objects will be called if you exit the program normally, by returning from main() or by calling exit(). If you call abort(), these destructors will not be called. If you want a graceful exit from a program which may be interrupted: 1. Avoid local objects which have destructors with important side effects. You have to assume that the destructors might not be called unless you disable interrupts during the lifetime of those objects. 2. Catch the keyboard interrupt and do whatever cleanup is needed; then call exit(). An unimportant side effect is freeing storage. An important side effect might be flushing an output buffer or restoring terminal attributes. -- Steve Clamage, TauMetric Corp, steve@taumet.com
Antony.Hodgson@sunbrk.FidoNet.Org (Antony Hodgson) (05/25/91)
In article <1991May24.045847.24401@colorado.edu> scholes@spot.Colorado.EDU (Genuine Bud Man) writes: > Please excuse me if this is a FAQ, or if I am missing something >painfully obvious, but destructors don't seem to be called when >the user hits ^C in Turbo C++. .. stuff deleted >The problem is that when the user types ^C, the destructors are not called, >and if the memory is in XMS or disk, then the XMS is not freed, or the >swap file not deleted. > I could easily write a ^C handler, and intercept ^C, but how >would the handler know who to call, since the class instances are >auto vars of another function? If ^C does the equivalent of exit(), then only global variable destructors are called. If it does the equivalent of abort(), no destructors are ever called. Borland C++ does have the atexit pragma, but since you can't pass parameters to it, you must have global variables available to tell you what swap files exist or what XMS blocks are not yet freed. Tony Hodgson ahodgson@hstbme.mit.edu * Origin: Seaeast - Fidonet<->Usenet Gateway - sunbrk (1:343/15.0)
s892992@minyos.xx.rmit.oz.au (Kendall Bennett) (05/27/91)
scholes@spot.Colorado.EDU (Genuine Bud Man) writes: > Please excuse me if this is a FAQ, or if I am missing something >painfully obvious, but destructors don't seem to be called when >the user hits ^C in Turbo C++. > I could easily write a ^C handler, and intercept ^C, but how >would the handler know who to call, since the class instances are >auto vars of another function? I could have the handler ignore ^C, >but I would like to have that functionality. I am pretty sure that if you call the exit() standard library function it calls the destructors for any AUTO variables, that is any instances that have been allocated on the stack. If the class instance was allocted in the heap, then it is up to the program to delete it - so I don't know how you would handle this one. See ya, Kendall Bennett (s892992@minyos.xx.rmit.oz.au)
steve@taumet.com (Stephen Clamage) (05/27/91)
s892992@minyos.xx.rmit.oz.au (Kendall Bennett) writes: | I am pretty sure that if you call the exit() standard library function it |calls the destructors for any AUTO variables, that is any instances that have |been allocated on the stack. If the class instance was allocted in the heap, |then it is up to the program to delete it - so I don't know how you would |handle this one. No, exit() will not call destructors for auto objects, since the language definition does not require that sort of bookkeeping. Destructors only for static objects only will be called when a program terminates via exit(). -- Steve Clamage, TauMetric Corp, steve@taumet.com
Stephen.Clamage@sunbrk.FidoNet.Org (Stephen Clamage) (05/28/91)
s892992@minyos.xx.rmit.oz.au (Kendall Bennett) writes: | I am pretty sure that if you call the exit() standard library function it |calls the destructors for any AUTO variables, that is any instances that have |been allocated on the stack. If the class instance was allocted in the heap, |then it is up to the program to delete it - so I don't know how you would |handle this one. No, exit() will not call destructors for auto objects, since the language definition does not require that sort of bookkeeping. Destructors only for static objects only will be called when a program terminates via exit(). -- Steve Clamage, TauMetric Corp, steve@taumet.com * Origin: Seaeast - Fidonet<->Usenet Gateway - sunbrk (1:343/15.0)
horstman@mathcs.sjsu.edu (Cay Horstmann) (05/29/91)
In article <1991May27.024810.2300@minyos.xx.rmit.oz.au> s892992@minyos.xx.rmit.oz.au (Kendall Bennett) writes: >scholes@spot.Colorado.EDU (Genuine Bud Man) writes: > >> Please excuse me if this is a FAQ, or if I am missing something >>painfully obvious, but destructors don't seem to be called when >>the user hits ^C in Turbo C++. > > I am pretty sure that if you call the exit() standard library function it >calls the destructors for any AUTO variables, that is any instances that have >been allocated on the stack. If the class instance was allocted in the heap, >then it is up to the program to delete it - so I don't know how you would >handle this one. > Fat chance. No such thing will happen. When you call exit(), the stack just gets popped, the free store given back wholesale. I am not sure whether STATIC destructors are run. Someone here surely knows the answer. Cay
jbuck@forney.berkeley.edu (Joe Buck) (05/29/91)
In article <1991May28.225141.1451@mathcs.sjsu.edu>, horstman@mathcs.sjsu.edu (Cay Horstmann) writes: |> In article <1991May27.024810.2300@minyos.xx.rmit.oz.au> s892992@minyos.xx.rmit.oz.au (Kendall Bennett) writes: |> > I am pretty sure that if you call the exit() standard library function it |> >calls the destructors for any AUTO variables, that is any instances that have |> >been allocated on the stack. If the class instance was allocted in the heap, |> >then it is up to the program to delete it - so I don't know how you would |> >handle this one. |> > |> Fat chance. No such thing will happen. When you call exit(), the stack |> just gets popped, the free store given back wholesale. I am not sure whether |> STATIC destructors are run. Someone here surely knows the answer. Cay's right; there's no provision in Turbo C++ or or cfront up through 2.1 that would allow you to have a control-C interrupt call destructors for the auto variables. When exceptions become commonly available, there will be a solution: the control-C signal handler can throw an exception, and if you want to catch it at the top level and exit, you can write your main() something like #include <signal.h> class IntSignal { // stuff goes here }; void intCatcher() throw IntSignal { throw IntSignal(); } int main (int argc, char ** argv) { // I'm being sloppy, should check the current status // of signal handling. signal (SIGINT, intCatcher); try { // body of main goes here } catch (IntSignal& isig) { cerr << "Caught a SIGINT, exiting\n"; exit(1); } } The exception handling mechanism will cause all auto values on the stack to have their destructors called. -- Joe Buck jbuck@galileo.berkeley.edu {uunet,ucbvax}!galileo.berkeley.edu!jbuck