[ros-kernel] a little gem I just put together
Royce Mitchell III
royce3 at ev1.net
Sat Mar 20 02:09:15 CET 2004
I just put together a little gem for troubleshooting memory
over/under-runs, and thought I'd share it with the rest of you. It even
works on C code if you compile as C++. All that's required is to include
this file and a define or two. There's probably some unhandled gotchas
in the classes, but I got it working with the C code I'm using now.
What makes this class so wonderful is it will assert if you even try to
read a value from out-of-bounds in the array combined with the fact that
you have to change very little of your C code ( if you don't count
compiling it "as C++" for this testing ).
-------------- next part --------------
// RedZonedMemory.h
// This code is (C) 2004, Royce Mitchell III,
// and released under the LGPL and BSD licenses
#ifndef REDZONEDMEMORY_H
#define REDZONEDMEMORY_H
#include <assert.h>
template <class T>
class RZMemory;
template <class T>
class RZMemoryRef;
template <class T>
class RZMemoryVal
{
RZMemory<T>* _rzm;
int _offset;
public:
RZMemoryVal ( RZMemory<T>* rzm, int offset ) : _rzm(rzm), _offset(offset)
{
}
RZMemoryRef<T> operator& ();
operator const T () const
{
assert(_rzm);
return _rzm->_p[_offset];
}
RZMemoryVal& operator = ( const T& t )
{
assert(_rzm);
_rzm->RZAssert ( _offset );
_rzm->_p[_offset] = t;
return *this;
}
bool operator != ( const RZMemoryVal& rhs ) const
{
return (T)*this != (T)rhs;
}
RZMemoryVal& operator &= ( const T& t )
{
assert(_rzm);
_rzm->RZAssert ( _offset );
_rzm->_p[_offset] &= t;
return *this;
}
RZMemoryVal& operator |= ( const T& t )
{
assert(_rzm);
_rzm->RZAssert ( _offset );
_rzm->_p[_offset] |= t;
return *this;
}
T operator & ( const T& t ) const
{
return ((T)*this) & t;
}
/*T operator | ( const RZMemoryVal& v ) const
{
return ((T)*this) | (T)v;
}
T operator | ( const T& t ) const
{
return ((T)*this) | t;
}*/
int operator >> ( int i ) const
{
return ((T)*this) >> i;
}
int operator << ( int i ) const
{
return ((T)*this) << i;
}
};
template <class T>
class RZMemoryRef
{
RZMemory<T>* _rzm;
int _offset;
RZMemoryRef* operator & ()
{
return this;
}
public:
void Delete()
{
assert ( _rzm );
_rzm->Delete();
_rzm = NULL;
}
RZMemoryRef() : _rzm(NULL)
{
}
RZMemoryRef ( RZMemory<T>* rzm, int offset=0 ) : _rzm(rzm), _offset(offset)
{
}
RZMemoryRef ( RZMemoryRef<T>* rzmf, int offset=0 ) : _rzm(rzmf._rzm), _offset(rzmf._offset+offset)
{
}
RZMemoryRef& operator = ( RZMemory<T>* rzm )
{
_rzm = rzm;
_offset = 0;
return *this;
}
RZMemoryRef operator + ( int i )
{
assert ( _rzm );
RZMemoryRef r ( this, i );
return r;
}
RZMemoryRef& operator += ( int i )
{
assert ( _rzm );
_offset += i;
return *this;
}
RZMemoryVal<T> operator* ()
{
assert ( _rzm );
return (*_rzm)[_offset];
}
RZMemoryVal<T> operator[] ( int i )
{
assert ( _rzm );
RZMemoryVal<T> v ( _rzm, _offset+i );
return v;
}
const RZMemoryVal<T> operator[] ( int i ) const
{
assert ( _rzm );
RZMemoryVal<T> v ( _rzm, _offset+i );
return v;
}
operator bool() const
{
return _rzm != 0;
}
};
template <class T>
class RZMemory
{
friend class RZMemoryVal<T>;
unsigned int _size;
T* _p;
public:
void Delete()
{
assert ( _p );
delete[] _p;
_p = NULL;
}
RZMemory ( unsigned int size ) : _size(size)
{
_p = new T[_size];
}
RZMemoryVal<T> operator[] ( int offset )
{
RZAssert ( offset );
RZMemoryVal<T> v ( this, offset );
return v;
}
const RZMemoryVal<T> operator[] ( int offset ) const
{
RZAssert ( offset );
RZMemoryVal<T> v ( this, offset );
return v;
}
void RZAssert ( int offset )
{
assert ( offset >= 0 && (unsigned int)offset < _size );
}
};
template <class T>
inline
RZMemoryRef<T>
RZMemoryVal<T>::operator& ()
{
RZMemoryRef<T> r ( _rzm, _offset );
return r;
}
#endif//REDZONEDMEMORY_H
More information about the Ros-kernel
mailing list