From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,e80a1497a689d8a5 X-Google-Attributes: gid103376,public From: lutz@iks-jena.de (Lutz Donnerhacke) Subject: Re: Ammo-zilla Date: 1999/10/30 Message-ID: #1/1 X-Deja-AN: 542510635 Distribution: world Content-Transfer-Encoding: 8bit References: <38120FAF.945ADD7D@hso.link.com> <7uutgd$87h$1@nnrp1.deja.com> <19991024.18033546@db3.max5.com> <38189268.43EB150F@mail.earthlink.net> <86ogdjtdwz.fsf@ppp-115-70.villette.club-internet.fr> <7vadsp$8q61@news.cis.okstate.edu> Content-Type: text/plain; charset=ISO-8859-1 Organization: IKS GmbH Jena Mime-Version: 1.0 User-Agent: slrn/0.9.5.7 (UNIX) Newsgroups: comp.lang.ada Date: 1999-10-30T00:00:00+00:00 List-Id: * David Starner wrote: >If garbage collection is not mandated, however, then it can't be relied on in >Ada code that might run under systems that don't garbage collect - i.e. >portable Ada code can't use it. Hence either you deallocate any memory >yourself, or suffer garbage leaks while running under a non-garbage >collecting system. Almost all memory leaks I came across were caused in an internal handling routine or in returning a pointer to an object leaving the 'free' procedure to the user. Internal routines should define there own access type (and so a seperate allocation pool) and only use pointers of that type. If the access type definition goes out of scope, all objects in this pool can be freed without any need for complex garbage collection. IIUC Ada 95 enforces this. Returning a pointer to an uplevel scope is bad design. If tagged type are used (most cases, due to the well known abstract factory pattern), you can replace your code in almost all cases in the following way: package Factories is type Factory is private; type Object is tagged private; type Object_Ptr is access Object; function Make_A_Pointer_To_Object(f: in Factory) return Object_Ptr; ... end Factories; procedure Do_Something(aFactory: in Factory) an_Object_Ptr: Object_Ptr := Make_A_Pointer_To_Object(aFactory); begin ... Free(po); -- Don't forget it on all possible exits! exception when others => Free(po); -- Don't forget it on all exceptions! raise; -- Fire again. end Do_Something; by: package Factories is type Factory is private; type Object is tagged private; function Make_A_Class_Wide_Object(f: in Factory) return Object'Class; ... end Factories; procedure Do_Something(aFactory: in Factory) an_Object: Object'Class := Make_A_Class_Wide_Object(aFactory); begin ... end Do_Something; In the rare cases where real pointers must be returned to build up a larger dynamic structure the whole structure should be implemented as a seperate package providing a Controlled object. It took me several weeks to determine this. Thanks to the help of the group regulars. I hope I wrote not so much bullshit.