roberts@BORIS.TYMNET.COM (Michael Roberts) (12/07/89)
Dear Doug Lea - dl@rocky.oswego.edu
cc: bug-g++@prep.ai.mit.edu
I am a new user of g++ version 1.35.0 and libg++ version 1.35.1. I greatly
appreciate the flexible container classes in that library. I have a possible
implementation error to report.
In the jargon of the GNU C++ Library manual, chapter 33, bottom of page 105,
the bug apears to be in d.del(k) of a particular Map class that I have used:
Integer.String.AVLMap. The problem is that when I have a Map of 3 (or more)
nodes, deleting the second node causes the first node to have its contents
replaced by the contents of the departing second node; the contents of the
third (and later) node(s) are unchanged.
I obtained the Map class in the following manner. I generated the files
Integer.String.Map.h and Integer.String.Map.cc via the genclass call
genclass -2 Integer val String ref Map
I generated the files Integer.String.AVLMap.h and Integer.String.AVLMap.cc
via the call
genclass -2 Integer val String ref AVLMap
In order to get my code to compile, I had to make some changes to those files.
I have run diff on all four, yielding four difference files which I have
included in this e-mailing:
Integer.String.Map.h.patch
Integer.String.Map.cc.patch
Integer.String.AVLMap.h.patch
Integer.String.AVLMap.cc.patch
Those .patch files are stuffed into patch.shar at the end of this message.
Source code name (code appears below):
g07.cc
Compiler command line:
g++ -g g07.cc Integer.String.Map.o Integer.String.AVLMap.o
Execution and output:
boris% a.out
Key Contents
___ ________
1 two
3 three
boris%
So we put in 3 Strings, deleted the second one, and the contents of the first
one is overwritten with the second one's contents. The output should have
been:
Key Contents
___ ________
1 one
3 three
I am running on a Sun 3/280 under SunOS 4.0.3
The g++ compiler is version 1.35.0 (as opposed to the library, which is
1.35.1).
I hope that's enough to help you find the problem. Thanx!
-Mike
Michael G. Roberts | Internet: roberts@calvin.Tymnet.COM
BT Tymnet, Inc | UUCP: {ames,sun}!oliveb!tymix!roberts
2560 North First Street | Voice: 408-922-7931
P.O.Box 49019, San Jose, CA 95161-9019 | Fax: 408-922-6125
---------- The Source Code ----------
#include <stream.h>
#include "String.h"
#include "Integer.h"
#include "Integer.String.AVLMap.h"
main()
{
IntegerStringAVLMap ISM("empty"); // default contents "empty"
ISM[Integer(1)] = String("one");
ISM[Integer(2)] = String("two");
ISM[Integer(3)] = String("three");
ISM.del(Integer(2)); // HERE IT IS!!!
cout << "\nKey Contents\n___ ________\n";
// output all the strings in the IntegerStringAVLMap
for (Pix i = ISM.first(); i != 0; ISM.next(i))
cout << ISM.key(i) << " " << ISM.contents(i) << "\n";
cout << "\n";
ISM.OK();
} /* main */
---------- patch.shar ----------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of shell archive."
# Contents: Integer.String.AVLMap.cc.patch
# Integer.String.AVLMap.h.patch Integer.String.Map.cc.patch
# Integer.String.Map.h.patch
# Wrapped by roberts@boris on Wed Dec 6 14:33:49 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Integer.String.AVLMap.cc.patch' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Integer.String.AVLMap.cc.patch'\"
else
echo shar: Extracting \"'Integer.String.AVLMap.cc.patch'\" \(586 characters\)
sed "s/^X//" >'Integer.String.AVLMap.cc.patch' <<'END_OF_FILE'
X0a1,2
X> // 12-04-89 Added IntegerCMP
X>
X25a28,29
X> #include "Integer.h"
X> #include "String.h"
X111a116,122
X> // From the usage of IntegerCMP results it is clear that cmp is to be
X> // loaded with 0 iff key == t->item. That is the semantics of !=. But
X> // there is the additional problem of the condition for returning a value
X> // < 0, which I do not understand. Perhaps compare(Integer&,Integer&) is
X> // the better choice. Yes! <0 means arg1 < arg2. This fits AVL being an
X> // ordered Map.
X> inline int IntegerCMP(Integer& key, Integer& item) {return compare(key, item);}
END_OF_FILE
if test 586 -ne `wc -c <'Integer.String.AVLMap.cc.patch'`; then
echo shar: \"'Integer.String.AVLMap.cc.patch'\" unpacked with wrong size!
fi
# end of 'Integer.String.AVLMap.cc.patch'
fi
if test -f 'Integer.String.AVLMap.h.patch' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Integer.String.AVLMap.h.patch'\"
else
echo shar: Extracting \"'Integer.String.AVLMap.h.patch'\" \(0 characters\)
sed "s/^X//" >'Integer.String.AVLMap.h.patch' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'Integer.String.AVLMap.h.patch'`; then
echo shar: \"'Integer.String.AVLMap.h.patch'\" unpacked with wrong size!
fi
# end of 'Integer.String.AVLMap.h.patch'
fi
if test -f 'Integer.String.Map.cc.patch' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Integer.String.Map.cc.patch'\"
else
echo shar: Extracting \"'Integer.String.Map.cc.patch'\" \(622 characters\)
sed "s/^X//" >'Integer.String.Map.cc.patch' <<'END_OF_FILE'
X0a1,2
X> // 12-04-89 Corrected ::seek
X>
X24a27,28
X> #include "Integer.h"
X> #include "String.h"
X41a46
X> #if 0
X42a48,58
X> #else
X> // This loop advances the Pix index i from first to last, each time checking
X> // that have not reached either the end of the Map or the desired key value
X> // item. The missing function IntegerEQ must be supplied. Integer.h has
X> // the following functions to choose from:
X> // compare signed comparison
X> // ucompare unsigned comparison not appropriate here
X> // ==
X> // != I'll try this one
X> for (Pix i = first(); i != 0 && (key(i) != item); next(i));
X> #endif
END_OF_FILE
if test 622 -ne `wc -c <'Integer.String.Map.cc.patch'`; then
echo shar: \"'Integer.String.Map.cc.patch'\" unpacked with wrong size!
fi
# end of 'Integer.String.Map.cc.patch'
fi
if test -f 'Integer.String.Map.h.patch' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Integer.String.Map.h.patch'\"
else
echo shar: Extracting \"'Integer.String.Map.h.patch'\" \(94 characters\)
sed "s/^X//" >'Integer.String.Map.h.patch' <<'END_OF_FILE'
X30c30,31
X< #include "Integer.defs.h"
X---
X> //#include "Integer.defs.h"
X> #include "Integer.h"
END_OF_FILE
if test 94 -ne `wc -c <'Integer.String.Map.h.patch'`; then
echo shar: \"'Integer.String.Map.h.patch'\" unpacked with wrong size!
fi
# end of 'Integer.String.Map.h.patch'
fi
echo shar: End of shell archive.
exit 0