Podobne
- Strona startowa
- Linux. .Mandrake.10.Podręcznik.Użytkownika.[eBook.PL] (3)
- (eBook) James, William The Principles of Psychology Vol. I
- (business ebook) Internet Marketing Tips for Newbie
- AutoCad 2005 PL podrecznik uzytkownika
- Polityka
- Jacqueline R. Kanovitz Constitutional Law, Twelfth Edition (2010)
- Saint Germain Studium alchemii
- Christie Agatha Trzynascie zagadek
- Michael Barrier The Animated Man, A Life of Walt Disney (2007)(2)
- Shepherd Joel Próba krwi i stali 02 Petrodor
- zanotowane.pl
- doc.pisz.pl
- pdf.pisz.pl
- qup.pev.pl
Cytat
Do celu tam się wysiada. Lec Stanisław Jerzy (pierw. de Tusch-Letz, 1909-1966)
A bogowie grają w kości i nie pytają wcale czy chcesz przyłączyć się do gry (. . . ) Bogowie kpią sobie z twojego poukładanego życia (. . . ) nie przejmują się zbytnio ani naszymi planami na przyszłość ani oczekiwaniami. Gdzieś we wszechświecie rzucają kości i przypadkiem wypada twoja kolej. I odtąd zwyciężyć lub przegrać - to tylko kwestia szczęścia. Borys Pasternak
Idąc po kurzych jajach nie podskakuj. Przysłowie szkockie
I Herkules nie poradzi przeciwko wielu.
Dialog półinteligentów równa się monologowi ćwierćinteligenta. Stanisław Jerzy Lec (pierw. de Tusch - Letz, 1909-1966)
[ Pobierz całość w formacie PDF ]
.The reports -r in r-R.rep or rather init in c-R.rep can bemodified to define a structure to circumvent this problem.The init report can be modified to generate a puto() method for Class whichuses the same technique as respondsTo() to display all method tags andaddresses.Piping the output of our sort program into the official sort(1) for checking mayproduce a surprise:$ sort r Sort.d | /usr/bin/sort c rsort: disorder: int quit (_self, const Object @ filter);There are more efficient ways for List_sort() to compact the list in the ringbuffer before passing it to qsort().Are we really correct in rotating it?125___________________________________________________________________________11Class MethodsPlugging Memory LeaksModern workstations have lots of memory.If a program looses track of a byte hereand there it will probably not make a whole lot of difference.However, memoryleaks are usually indicative of algorithmic errors either the program reacts inunexpected ways to strange input or, worse, the program was inadvertentlydesigned to break connections to dynamically allocated memory.In this chapter wewill look at a general technology available with object-oriented programming whichcan be used, among other things, to combat memory leaks.11.1 An ExampleAll resources acquired by a program should be properly recycled.Dynamic memoryis a resource and production programs should certainly be checked for memoryleaks.As an example, consider what happens when we make a syntax error whileusing the calculator developed in the third and fifth chapter:$ value(3 * 4) bad factor: 0x0The recursive descent algorithm tries to build an expression tree.If somethinggoes wrong, the error() function uses longjmp() to eliminate whatever is on thestack and continue processing in the main program.The stack, however, containsthe pieces of the expression tree built thus far.If there is a syntax error, thesepieces are lost: we have a memory leak.This is, of course, a standard problem inconstructing interpreters.NeXTSTEP provides a simple application MallocDebug which can be used tolocate at least some of the more serious problems.If we link value with -lMalloc-Debug, the standard versions of malloc() and related functions are replaced by amodule that can communicate with the MallocDebug application.We start Malloc-Debug after value, connect the two, and push a button Leaks once we havereceived the first error message.Unfortunately, the output is simply:No nodes.MallocDebug uses a fairly naive method to check for leaks: it has a list of all allo-cated areas and scans the words in the client task to see if they point to allocatedareas.Only areas to which no word in the client task points are considered to bememory leaks.For the input(3 * 4) sum() will have the first subtree built by product() before factor() runs into the endof the input line.However, when error() clips the stack from factor() back tomain(), the address of the root of this subtree is still in the local variable result ofsum() and, by chance, does not get overwritten in the longjmp().The remaining126 11 Class Methods Plugging Memory Leaks___________________________________________________________________________nodes are connected to the root, i.e., from the point of view of MallocDebug, allnodes can still be reached.However, if we enter another expression the old stackis overwritten and MallocDebug will find the leak.value:$ value(3 * 4) bad factor: 0x01 + 34MallocDebug:Zone: Address: Size: Function:default 0x050ec35c 12 mkBin, new, product, sum,factor, product, sum, stmtIf value is compiled with debugging information, we can start a debugger in asecond window and investigate the leak:$ gdb valueGDB is free software.(gdb) attach 746Attaching program `value , pid 7460x5007be2 in read ()(gdb) print * (struct Bin *) 0x050ec35cReading in symbols for mathlib.c.done.$1 = {type = 0x8024,left = 0x50ec334,right = 0x50ec348}(gdb) print process(0x050ec35c)Reading in symbols for value.c.done.$3 = void(gdb)The GNU debugger can be attached to a running process.With print we can displaythe contents of the leaky node if we copy the address from the MallocDebug win-dow and supply the proper type: mkBin() was the original caller of malloc(), i.e.,we must have obtained a struct Bin.As the output shows, print can even call amethod like process() in value and display the result.The output from process()appears in the window where value is running:$ value(3 * 4) bad factor: 0x01 + 3412The memory leak is alive and well.11.2 Class Methods 127___________________________________________________________________________11.2 Class MethodsHow do we plug this specific memory leak? The leak has occurred by the timeerror() returns to the main loop.Either we collect and release all expression piecesbefore longjmp() is executed, or we need a different way to reclaim the allocatednodes.Collecting the pieces is a lost cause because they are held by various activa-tions of the functions involved in the recursive descent algorithm.Only each activa-tion knows what must be released, i.e., in place of a longjmp() we would have tocope with error returns in every function.This is likely to be botched once the pro-gram is later extended.Designing a reclamation mechanism is a much more systematic approach forsolving this problem.If we know what nodes are currently allocated for the expres-sion tree we can easily release them and reclaim the memory in case of an error.What we need are versions of new() and delete() which maintain a linear list ofallocated nodes which a function like reclaim() can traverse to free memory.Inshort, for expression tree nodes we should overwrite what new() and delete() do.delete() is sent to objects, i.e., it is a method that can be given dynamic linkageso that it may be overwritten for a subtree of the class hierarchy.new(), however,is sent to a class description.If we want to give new() dynamic linkage, we mustadd its pointer to the class description of the class description object, to which wewant to send new():aNode Node NodeClass" " ?
[ Pobierz całość w formacie PDF ]