c++.stl.port - potential anti-clobbering design (of containers & iterators) vs. actuality -- especially, strings
- Richard Haney <Richard_member pathlink.com> Mar 22 2004
Evidently, it is easy to get into trouble with code like *scanOut = *scanIn; where scanOut and scanIn are (say, string) iterators. For example, you apparently only get one chance to store something in any given location with "*scanOut = something;", at least while the value of scanOut is unchanged. It is not clear if is ok to execute "scanSave = scanOut;" and then execute, say, " *scanOut = something; *scanSave = something_else;" so that neither of the iterators scanOut and scanSave has been used explicitly more than once as an assignment l-value to store something at a given location. Also, it is not clear whether the container classes and iterators (and their operators) are defined so that the container objects will automatically reallocate and expand storage where "*scanOut = something;" amounts to storing items at one passed the last element (i.e., at location container.end() ). Conceivably, the definition of iterators could keep track of what particular container objects their values are derived from and thus make reallocation adjustments as necessary. An example of these difficulties can be found at <c++.stl.port/182> with a correction at <c++.stl.port/183> My solution was to 1) use the "string.push_back(char ch)" function for storage in place of " *scanOut = something;" and to 2) put all the conditional statements into one extended "if(....) .... else if(....) .... else if(....) ... .... else ...." chain so that only one of the statement parts would be executed. Also, it is not clear whether the string class uses some efficient storage reservation and reallocation scheme to reduce potential overhead of reallocating storage with each and every appending of single characters at the end of the string. For example, an efficient reallocation scheme could automatically reserve, say, twenty extra, unused spaces for the string each time a reallocation is made. That would, in general, reduce the reallocation overhead to one twentieth of what it might be without any reservation of unused space. Perhaps, a better reallocation algorithm would strictly reserve, say, twenty extra spaces and to also reserve say 100 extra spaces on a lower, shared priority basis with other requests for storage; in that way, the overhead might usually be reduced to one one-hundredth of the reallocation overhead that would occur with no reservation of unused space. Evidently, the vector class allows explicit requests for reserved space, but the functions provided do not seem to provide the automated flexibility contemplated here for maximum efficiency. It would be desirable to have very simple, fast inline code to test for space presently available each time a new element is added. When reserved space is entirely consumed, a function could be called to reallocate space, and the user could override that function to provide his own optimal parameters of reallocation; he could also call another function (perhaps an overridden function from a base class) to take care of reallocation details.
Mar 22 2004