Dan Kloke wrote: > yikes! still clear as mud. > since the array wasnt being resized i thought that the assignment must > be a mixup. i didnt get the purpose of the function. i thought nodes was > already loaded.. > > but cant we just measure the array before resizing and adding the new > node? i still dont get we need an external counter. at any time the > array is "full", and just needs to be measured and extended by one. > still dont need to save or pass the size globally..it already implicit > in the var paramater nodes array.
That's possible, but it's also the least efficient way of using a dynamic array. Frequent, small resizes of an array will lead to memory fragmentation because each time you call SetLength, the memory manager will allocate a slightly larger block and discard the smaller one. The next time around, it cannot re-use that smaller block because it needs a block that's just slightly larger, not smaller, than the one it already has. The time taken to copy all the contents of the old array into the new array will also add up. The same applies to strings. > also, isn't it ugly (though not illegal) to assign a value to a > parameter inside the function? That's why "var" and "out" parameters exist. It's done all the time. It's absolutely essential if your function needs to return more than one value, and this function needs that: It returns a filled list of nodes, and it also returns the length of that list. > or is this necessary for type compatability? > > > PObjArray = array of tsxGNODE; > > procedure tsGrpExtractNodes(grp: tsxGROUP; var nodes: PObjArray); > var > pChildNode: tsxSOBJ; > objtype: tsxSOBJTYPE; > begin > pChildNode:= tsxGNodeGetFirstChild(grp); > while (pChildNode <> nil) do begin > objtype:= tsxSobjGetType(pChildNode); > if ((objtype = e_tsxGROUP) or (objtype = e_tsxIKGROUP)) then begin > grp:= pChildNode;//lets not do this, just put pChildNode right into the > recursive call > tsGrpExtractNodes(pChildNode, nodes); > end > else begin > //adding to array > SetLength(nodes,Length(nodes)+1); > nodes[Length(nodes)-1]:= pChildNode; > end; > pChildNode:= tsxGNodeGetNext(pChildNode); > end; > end; > > and i dont get why you resized the array AFTER the recursive call in > your nested-function approach.. isnt it too late then? > > Count := 0; > ExtractNodesWorker(grp, nodes, Count); > SetLength(nodes, Count); I'm assuming that before he calls the function, Richard already has some way of assuring that the array is large enough to hold all the nodes that this function might try to return. If he didn't, then his original function would never have worked. But since we don't return the actual number of nodes the function finds, there won't be any other way of determining how many of the array elements are occupied when the function returns. The code above takes the count and truncates the array to the amount determined by the recursive function. That way, we don't need to report how many elements are occupied in the array because the answer is always the same: all of them -- we've gotten rid of any elements that aren't full. -- Rob __________________________________________________ Delphi-Talk mailing list -> [email protected] http://www.elists.org/mailman/listinfo/delphi-talk
