[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
pointer corruption bug w/ template classes
From: |
Ian Williams |
Subject: |
pointer corruption bug w/ template classes |
Date: |
Wed, 16 May 2001 19:59:29 -0700 |
Hi,
There appears to be a bug with the g++ compiler when using template classes
and the attached program shows the issue.
The version of the g++ compiler used is egcs-c++-1.1.2-30 (from RedHat 6.2)
and the hardware was an SGI 230 system w/ Pentium III 733 MHz with Via
Apollo Pro chip set and PC133 SDRAM.
The template class is used to define a buffer and a further subClass deals
with a buffer of arrays (such as points). It seems that when an array class
is instantiated and an element is added (via the BufferV:add method) the
address of the array address gets corrupted through the call. To show this
the program prints out the data before, during and after the BufferV:add
call and the results after entering BufferV:add yield garbage.
As documented in the program, the weird thing is that for the cases where
BufferV is instantiated with F=int[3] or F=float[3], adding 3 to the array
index in BufferV:add delivers the correct elements. I couldn't find any
similar thing when BufferV is intantiated with F=double[3] though.
Thanks in advance for any information/suggestions.
Ian M. Williams.
----------------------------------------------------------------------------
-----------------------------------
/* Compile: g++ -o test test.c++ */
#include <string.h>
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
template <class T, class F> // T="To" the storage format for the buffer
// F="From", the storage format from which
the
// data comes
class Buffer
{
public:
Buffer(int length=100, char* label=NULL);
virtual ~Buffer();
virtual bool add(F item) = 0;
T* buf() const;
int bufLength() const;
bool canAddTo();
void reset();
protected:
T* mBuffer;
int mInBuffer;
private:
Buffer(const Buffer<T,F>& b);
int mBufferLength;
bool mOverflowReported;
char* mBufferName;
};
template <class T, class F>
Buffer<T,F>::Buffer(int length, char* label) :
mBufferLength(length), mOverflowReported(FALSE),
mBuffer(NULL), mInBuffer(0), mBufferName(NULL)
{
mBuffer = new T[length];
if (label != NULL)
{
mBufferName = new char[strlen(label)+1];
strcpy(mBufferName,label);
}
}
template <class T, class F>
Buffer<T,F>::Buffer(const Buffer<T,F>& b) :
mBufferLength(0), mOverflowReported(FALSE),
mBuffer(NULL), mInBuffer(0), mBufferName(NULL)
{
}
template <class T, class F>
Buffer<T,F>::~Buffer()
{
if (mBuffer != NULL)
{
delete [] mBuffer;
mBuffer = NULL;
mBufferLength = 0;
reset();
}
if (mBufferName != NULL)
{
delete [] mBufferName;
mBufferName = NULL;
}
}
template <class T, class F>
T*
Buffer<T,F>::buf() const
{
return mBuffer;
}
template <class T, class F>
int
Buffer<T,F>::bufLength() const
{
return mInBuffer;
}
template <class T, class F>
bool
Buffer<T,F>::canAddTo()
{
if ( mInBuffer == mBufferLength )
{
if (!mOverflowReported)
{
mOverflowReported = TRUE;
if (mBufferName != NULL)
cerr << mBufferName << ": ";
cerr << "Buffer overflow\n";
}
return FALSE;
}
return TRUE;
}
template <class T, class F>
void
Buffer<T,F>:: reset()
{
mOverflowReported = FALSE;
mInBuffer = 0;
}
//////////////// Subclass for buffering arrays /////////////////////////////
template <class T, class F>
class BufferV : public Buffer<T,F>
{
public:
BufferV(int length=100, char* label=NULL);
virtual ~BufferV();
virtual bool add(F item);
private:
BufferV(const BufferV<T,F>& b);
};
template <class T, class F>
BufferV<T,F>::BufferV(int length, char* label) : Buffer<T,F>(length,label)
{
}
template <class T, class F>
BufferV<T,F>::BufferV(const BufferV<T,F>& b) : Buffer<T,F>(b)
{
}
template <class T, class F>
BufferV<T,F>::~BufferV()
{
}
template <class T, class F>
bool
BufferV<T,F>::add(F item)
{
cout << "item = " << item[0] << ", "
<< item[1] << ", " << item[2] << endl;
/*
For some reason the following line yields the correct output
when instantiated with F = int[3] or F = float[3]
cout << "item = " << item[0+3] << ", "
<< item[1+3] << ", " << item[2+3] << endl;
*/
if (Buffer<T,F>::canAddTo())
{
cout << "mBuffer[" << mInBuffer << "] = ";
for (int i=0 ; i<3 ; i++) {
/*
See above when instanciated with F = int[3] and float[3]
mBuffer[mInBuffer][i] = item[i+3];
*/
mBuffer[mInBuffer][i] = item[i];
cout << mBuffer[mInBuffer][i] << ", ";
}
cout << endl;
mInBuffer++;
return TRUE;
}
return FALSE;
}
//typedef int Dxyz[3], *DxyzP;
//typedef float Dxyz[3], *DxyzP;
typedef double Dxyz[3], *DxyzP;
static BufferV<Dxyz,Dxyz> faceVertexBuf(10,"faceVertexBuf");
Dxyz input_points[4]={ {1.0, -1.0, 1.0},{1.0, 1.0, -1.0},
{1.0, 1.0, 1.0},{1.0, -1.0, 1.0} };
int main (int argc, char* argv[])
{
int i = 0, index;
faceVertexBuf.reset();
for (i=0;i<4; i++) {
index = faceVertexBuf.bufLength();
Dxyz temp = {input_points[i][0],
input_points[i][1],
input_points[i][2]};
cout << "Input = " << temp[0] << ", "
<< temp[1] << ", " << temp[2] << endl; ;
faceVertexBuf.add(temp);
DxyzP tempP = faceVertexBuf.buf()[index];
cout << "Output = " << tempP[0] << ", "
<< tempP[1] << ", " << tempP[2] << endl; ;
}
return 0;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- pointer corruption bug w/ template classes,
Ian Williams <=