[ Pobierz całość w formacie PDF ] .c will call delete() after it is done with an expression:if (setjmp(onError)){ ++ errors;reclaim(Node(), delete);}while (gets(buf))if (scan(buf)){ void * e = stmt();if (e){ printf("\t%g\n", exec(e));delete(e);}}If something goes wrong and error() is called, reclaim() is used to apply delete() toall nodes on the chain:% Node reclaim {%castswhile (nodes)how(nodes);}This plugs the memory leak described at the beginning of this chapter MallocDe-bug does not find any leaks, neither immediately after an error nor later.For testpurposes we canreclaim(Node, sunder);after an error and let MallocDebug demonstrate that we really have lost nodes.The elegance of the scheme lies in the fact that the entire mechanism is encap-sulated in the base class Node and inherited by the entire expression tree.Given140 11 Class Methods Plugging Memory Leaks___________________________________________________________________________class functions, we can replace new() for a subtree of the class hierarchy.Replac-ing new() exactly for all nodes, but not for symbols or the symbol table, providesreclamation for broken expressions without damaging variables, functions, and thelike.Technically, reclaim() is declared as a class method.We do not need the abilityto overwrite this function for a subclass of Node, but it does leave room for expan-sion.reclaim() permits a choice as to what should be applied to the chain.In caseof an error this will be delete(); however, if we save an expression for a userdefined function in a Fun symbol, we need to apply sunder() to the chain to keepthe next error from wiping out the expression stored in the symbol table.When afunction is replaced, setfun() will delete the old expression and delete() still usessunder() this is why sunder() does not demand to find its argument on thechain.11.5 SummaryClass Methods are applied to class descriptions, rather than to other objects.Weneed at least one class method: new() creates objects from a class description.Just like other methods, class methods can have static or dynamic linkage, butthe syntax of ooc only permits static linkage for class methods that apply to the rootmetaclass.Therefore, the term class method has been introduced here to onlydescribe a method with dynamic linkage that is applied to a class description.Since there are relatively few class descriptions, we can provide the dynamiclinkage for a class method by storing it in the class description itself to which itapplies.This has two advantages: we can overwrite class methods for a subclasswithout introducing a new metaclass to store it; and our basic scheme remainsintact where objects point to class descriptions, class descriptions point to theirown descriptions, and the latter can all be stored in struct Class, i.e., they will allpoint to Class, thus completing the class hierarchy in a clean fashion.Defining new() as a class method for Object rather than as a method withstatic linkage for Class permits redefining new() for subtrees of the class hierarchy.This can be used for memory allocation tracking, memory sharing, etc.ooc makesno provisions for extending the data part of a class description.If it did, a classmethod could have local data applicable to its class as a whole and we could countobjects per class, etc.static variables in an implementation file are not quite thesame because they exist once for the class and all its subclasses.There is a tradeoff between new() and a constructor.It is tempting to do allthe work in new() and leave the constructor empty, but then invariants normallyestablished by the constructor can break once new() is overwritten.Similarly, aconstructor is technically capable of substituting a different memory area in place ofthe one passed in from new() this was demonstrated in the implementation ofAtom in section 2.6 but a proper life cycle for this memory is difficult to main-tain.11.6 Exercises 141___________________________________________________________________________As a rule of thumb, class methods like new() should only connect an allocationfunction with a constructor and refrain from doing any initializations themselves.Allocation functions such as allocate() should initialize the class description pointer too much can go horribly wrong if they do not.Reclamation functions such asdelete() should let the destructor dispose of the resources which the constructorand the object s life cycle have accumulated, and only pass the empty memory areato a recycler function like free():allocate() free()anObject anObjectctor() dtor()aThing aThingnew() delete()aThingThere is a balance: allocate() and free() deal with the same region of memory; bydefault, new() gives it to its constructor, delete() to its destructor; and the con-structor and destructor only deal with resources represented inside the object.new() and delete() should only be overwritten to interfere with the flow of memoryfrom allocate() to free().11.6 ExercisesFor the ooc parser it makes absolutely no difference, if class methods are describedbefore or after dynamically linked methods in the class description file, i.e., if %+precedes or follows %-.There is, however, a convincing point in favor of thearrangement described in this chapter.Why can the separators not be repeated toachieve an arbitrary mix of both types of methods?There is a rather significant difference once delete() is implemented withdynamic linkage.What can no longer be passed to delete()?It is not helpful to move value() back into the abstract base class Symbol andgive it dynamic linkage there.mathvalue() is applied to a Math symbol andrequires a function argument, value() is applied to a Var or Const symbol and hasno use for an argument.Should we use variable argument lists?We can detect recursion among user defined functions.We can use words like$1 to support functions with more than one parameter.We can even add parame-ters with names that hide global variables.If we add a generic pointer to the data area of Class in Object.d class methodscan attach a chain of private data areas there.This can be used, e.g., to countobjects or to provide object lists per class
[ Pobierz całość w formacie PDF ] zanotowane.pldoc.pisz.plpdf.pisz.plmikr.xlx.pl
|