home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!stanford.edu!apple!applelink.apple.com
- From: GER.XSE0039@AppleLink.Apple.COM (Germany - C Brinkschulte Berlin,IDV)
- Newsgroups: comp.sys.mac.oop.macapp3
- Subject: Re:Re: Bug in TDynamicArray
- Message-ID: <724522278.5036135@AppleLink.Apple.COM>
- Date: 16 Dec 92 15:46:00 GMT
- Sender: daemon@Apple.COM
- Organization: AppleLink Gateway
- Lines: 81
-
- >The problem arises when a TDynamicArray is cloned while an Iterator which was
- >used for the TDynamicArray is stil in scope. TDynamicArray has a field named
- >fIteratorPtr, which contains a linked list of Iterators currently in use for
- >the TDynamicArray. When a TDynamicArray gets cloned, both (the old and the
- >cloned Array's) fIteratorPtrs point to the same Iterator. If the
- >CArrayIterator
- >is destructed, the fIteratorPtr of the cloned TDynamicArray points to an
- >invalid Memory-Address.
-
- Response:
-
- >By golly, you're right! How they ever let one this obvious slip through
- >I'll never know. TDynamicArray should have a Clone override that sets
- >fIteratorPtrs = NULL.
-
- >What the heck are you doing that creates a clone of the array while you're
- >iterating it? It seems to me that the only time that linked list of iterators
- >get used is when iterations are nested -- unless you are instantiating
- >iterators as seperate objects and not by the usual method on the stack.
-
-
- *Every* Iterator inserts itself into the linked list of Iterators found inside
- TDynamicArray it is attached to. This is necessary, because the Iterators have
- to be informed, if an element gets inserted into or deletetd from the Array
- while iterating over the Array. They have to be informed, so they can adjust to
- the new size of the Array. (A very nice feature, by the way). It is not
- necessary to have multiple or nested Iterators to trigger the bug.
-
- In fact, it is very easy to run into the problem. The following code is an
- example on how _EASY_ it is:
-
- TDynamicArray* aDynamicArray = new TDynamicArray;
- aDynamicArray->IDynamicArray (0, sizeof (MyStruct));
-
- CArrayIterator iter (aDynamicArray);
-
- for ( ArrayIndex index = iter.FirstIndex ();
- iter.More ();
- index = iter.NextIndex ())
- {
- [do something]
- }
-
- TDynamicArray* clonedArray = aDynamicArray->Clone ();
-
- You dont have to be iterating over the array if you like to run into the
- problem. The point is that as long as the Iterator is in scope, (the block the
- Iterator was declared), its destructor does _NOT_ get called. So it stays
- inside the linked list of Iterators attached to the DynamicArray. This leads to
- the conclusion that one never should clone a List or DynamicArray after or
- while iterating over the array.
-
- Another workaround for this problem is to make a seperate block for the
- Iterator so its destructor gets called (which removes itself from the linked
- list of Iterators) before cloning the Array:
-
- TDynamicArray* aDynamicArray = new TDynamicArray;
- aDynamicArray->IDynamicArray (0, sizeof (MyStruct));
-
- { // Extra block to limit the scope of the Iterator
- CArrayIterator iter (aDynamicArray);
-
- for ( ArrayIndex index = iter.FirstIndex ();
- iter.More ();
- index = iter.NextIndex ())
- {
- [do something]
- }
- }
-
- TDynamicArray* clonedArray = aDynamicArray->Clone ();
-
- I think this explains the range of the problem better than my first link.
-
- Please send me a copy of any replys, because I am not part of MacAppTech$
- anymore (it has flooded my In-Box too much).
-
- Carsten Brinkschulte
- Berlin
- GER.XSE0039
-
-