[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