[comp.lang.c++] Generic vector lib bug???

samperi@marob.MASA.COM (Dominick Samperi) (01/10/89)

The C++ program below seems to indicate that the generic vector library
(the one requiring vector.h) contains a bug. I may be using the library
incorrectly, since it really isn't documented anywhere. The comments
at the beginning of the program describe the bug, and also point out
that the bug goes away when a hand-made vector package is used.

Any comments, suggestions, etc. would be appreciated...

Dominick Samperi
samperi@acf8.nyu.edu
uunet!hombre!samperi


/*
*  bug.c -- Bug in generic vector library????
*
*  The instantiation (near the bottom) of x by initializing it from
*  select results in some kind of corruption when the generic vector.h
*  and library are used. The corruption can be seen in the output generated
*  in counter::counter(counter& cnt), where cnt is destroyed after the new
*  calls (on my machine). The generic library (and bug) is selected by
*  uncommenting the #define VECTOR below. With VECTOR not defined, a hand-
*  made vector type is used, and there are no problems.
*/

#include <stream.h>

/* #define VECTOR /* Uncomment this to use vector.h and cause a BUG! */

#ifdef VECTOR

#include <vector.h>

declare(vector,int) ;	// NOTE: no spaces allowed between () here!
implement(vector,int) ;	// NOTE: this macro should only be expanded in ONE file.
			//       ^^^^ can't say the implXXX word here, since
			//            the macro processor doesn't understand //!

#else

class vector {
	int *v ;
	int sz ;
public:
	vector(int) ;
	vector(vector&) ;
	~vector() ;
	int size()	{ return sz ; }
	int& operator[](int) ;
	vector operator=(vector) ;
} ;

vector::vector(int siz)
{
	sz = siz ;
	v = new int[sz] ;
}

vector::vector(vector& vv)
{
	sz = vv.size() ;
	v = new int[sz] ;
	for(int i = 0 ; i < sz ; i++) v[i] = vv[i] ;
}

vector::~vector()
{
	delete v ;
}

int& vector::operator[](int i)
{
	return v[i] ;
}

vector vector::operator=(vector vv)
{
	for(int i = 0 ; i < sz ; i++) v[i] = vv[i] ;
	return *this ;
}

#endif

class counter {
#ifdef VECTOR
	vector(int) *low, *high, *incr, *count ;
#else
	vector *low, *high, *incr, *count ;
#endif
	int sz ;
public:
#ifdef VECTOR
	counter(vector(int)&, vector(int)&, vector(int)&) ;
#else
	counter(vector&, vector&, vector&) ;
#endif
	counter(counter&) ;
	~counter() ;
	int size() { return low->size() ; }
	void reset()	{ *count = *low ; }
	void print() ;
	int operator[](int i)	{ return (*count)[i] ; }
} ;

void counter::print()
{
	cerr << "Counter(low,high,incr,count): \n" ;
	for(int i = 0 ; i < sz ; i++)
	{
		cerr << i << ": " << (*low)[i] << " " << (*high)[i] << " "
		     << (*incr)[i] << " " << (*count)[i] << "\n" ;
	}
}

#ifdef VECTOR
counter::counter(vector(int)& lo, vector(int)& hi, vector(int)& inc)
#else
counter::counter(vector& lo, vector& hi, vector& inc)
#endif
{
	sz = lo.size() ;
#ifdef VECTOR
	low = new vector(int)(sz) ;
	high = new vector(int)(sz) ;
	incr = new vector(int)(sz) ;
	count = new vector(int)(sz) ;
#else
	low = new vector(sz) ;
	high = new vector(sz) ;
	incr = new vector(sz) ;
	count = new vector(sz) ;
#endif
	*low = lo ;
	*high = hi ;
	*incr = inc ;
	*count = lo ;
}

counter::counter(counter& cnt)
{

cerr << "cnt param before instantiation:\n" ;
cnt.print() ;

	sz = cnt.size() ;
#ifdef VECTOR
	low = new vector(int)(sz) ;
	high = new vector(int)(sz) ;
	incr = new vector(int)(sz) ;
	count = new vector(int)(sz) ;
#else
	low = new vector(sz) ;
	high = new vector(sz) ;
	incr = new vector(sz) ;
	count = new vector(sz) ;
#endif

cerr << "cnt after instantiation:\n" ;
cnt.print() ;

	*low = *cnt.low ;
	*high = *cnt.high ;
	*incr = *cnt.incr ;
	*count = *low ;
}

counter::~counter()
{
	delete count ;
	delete incr ;
	delete high ;
	delete low ;
}

ostream& operator<<(ostream& s, counter& c)
{
	s << "[ " ;
	for(int i = 0 ; i < c.size() ; i++)
		s << form("%2d", c[i]) << " " ;
	return s << "]\n" ;
}

main()
{
#ifdef VECTOR
	vector(int) low(3), high(3), incr(3) ;
#else
	vector low(3), high(3), incr(3) ;
#endif

	for(int i = 0 ; i < 3 ; i++)
	{
		low[i] =  1 ;
		high[i] = 5 ;
		incr[i] = 1 ;
	}

	counter select(low, high, incr) ;

	select.print() ;

	counter x = select ;
}