Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Cygwin environment and Bounds issues

Author: Steffen Jakob

Date: 12:31:58 02/19/05

Go up one level in this thread


On February 19, 2005 at 14:16:43, Charles Roberson wrote:

>
>  When I commnent out 10 bytes of unused variables I get different
>  node counts in my benchmark only at 7ply or greater.
>  I do no mallocs or such, thus sounds to me like a bounds or stack
>  problem.
>
>    Does anybody know a good bounds checker/ memory error detector that
>   runs in the cygwin envrionment or runs outside of it that doesn't need
>   to be instrumented into the binary????

No, but I wrote a simple helper template class which wraps C-arrays for Hossa
which helped me in the past to detect some bounds violations. Here is the code
(I hope it's still readable after copy&pasting):


/**
 * @file
 *
 * $Id: Array.hpp,v 1.13 2005/01/25 00:06:49 saj Exp $
 *
 * (C)opyright 198?-2005 by Steffen A. Jakob
 *
 * @author Steffen A. Jakob <steffen@jakob.at>
 *
 * @brief A wrapper class for C arrays which is able to check bounds.
 */

#ifndef _HOSSA_ARRAY_HPP_
#define _HOSSA_ARRAY_HPP_

#include "switches.hpp"
#include "IO.hpp" 		// for LOG

namespace hossa {

	/**
	 * This template class is meant as a wrapper class for C-arrays
	 * with constant size which provides bounds checking. Bounds
	 * checking can be disabled without performance differences
	 * compared to C-arrays.
	 *
	 * Bounds checking is done if the variable "NDEBUG" is undefined.
	 *
	 * E.g.:
	 * #include "Array.hpp"
	 * #undef NDEBUG
	 *
	 * Array<int, 64> board;
	 * std::cout << board[E2] << std::endl; // ok
	 * std::cout << board[64] << std::endl; // will fire an assert()
	 * int sq1 = pst[F6]; // ok
	 * int sq2 = pst[100]; // another assert()
	 *
	 * const Array<int, 4> anArray(2, 3, 5, 7); // Ctor for initializing consts
	 *
	 * @param T The type of the array elements.
	 * @param S The size of the array.
	 */
	template <typename T, int S>
	class Array {
	public:
		/**
		 * Maximum number of array elements.
		 */
		static const int SIZE = S;

		/**
		 * Default ctor. The array elements are left uninitialized.
		 */
		Array() {
		}

		/**
		 * A somehow ugly ctor which takes up to 65 T values.
		 */
		Array(T  v0      , T  v1 = T(), T  v2 = T(),
			  T  v3 = T(), T  v4 = T(), T  v5 = T(),
			  T  v6 = T(), T  v7 = T(), T  v8 = T(),
			  T  v9 = T(), T v10 = T(), T v11 = T(),
			  T v12 = T(), T v13 = T(), T v14 = T(),
			  T v15 = T(), T v16 = T(), T v17 = T(),
			  T v18 = T(), T v19 = T(), T v20 = T(),
			  T v21 = T(), T v22 = T(), T v23 = T(),
			  T v24 = T(), T v25 = T(), T v26 = T(),
			  T v27 = T(), T v28 = T(), T v29 = T(),
			  T v30 = T(), T v31 = T(), T v32 = T(),
			  T v33 = T(), T v34 = T(), T v35 = T(),
			  T v36 = T(), T v37 = T(), T v38 = T(),
			  T v39 = T(), T v40 = T(), T v41 = T(),
			  T v42 = T(), T v43 = T(), T v44 = T(),
			  T v45 = T(), T v46 = T(), T v47 = T(),
			  T v48 = T(), T v49 = T(), T v50 = T(),
			  T v51 = T(), T v52 = T(), T v53 = T(),
			  T v54 = T(), T v55 = T(), T v56 = T(),
			  T v57 = T(), T v58 = T(), T v59 = T(),
			  T v60 = T(), T v61 = T(), T v62 = T(),
			  T v63 = T(), T v64 = T()
			  )
		{
			H_ASSERT(SIZE <= 65); // has to be adjusted if necessary
			int n = 0;
			if(SIZE > 0) { t[n++] = v0; }
			if(SIZE > 1) { t[n++] = v1; }
			if(SIZE > 2) { t[n++] = v2; }
			if(SIZE > 3) { t[n++] = v3; }
			if(SIZE > 4) { t[n++] = v4; }
			if(SIZE > 5) { t[n++] = v5; }
			if(SIZE > 6) { t[n++] = v6; }
			if(SIZE > 7) { t[n++] = v7; }
			if(SIZE > 8) { t[n++] = v8; }
			if(SIZE > 9) { t[n++] = v9; }
			if(SIZE > 10) { t[n++] = v10; }
			if(SIZE > 11) { t[n++] = v11; }
			if(SIZE > 12) { t[n++] = v12; }
			if(SIZE > 13) { t[n++] = v13; }
			if(SIZE > 14) { t[n++] = v14; }
			if(SIZE > 15) { t[n++] = v15; }
			if(SIZE > 16) { t[n++] = v16; }
			if(SIZE > 17) { t[n++] = v17; }
			if(SIZE > 18) { t[n++] = v18; }
			if(SIZE > 19) { t[n++] = v19; }
			if(SIZE > 20) { t[n++] = v20; }
			if(SIZE > 21) { t[n++] = v21; }
			if(SIZE > 22) { t[n++] = v22; }
			if(SIZE > 23) { t[n++] = v23; }
			if(SIZE > 24) { t[n++] = v24; }
			if(SIZE > 25) { t[n++] = v25; }
			if(SIZE > 26) { t[n++] = v26; }
			if(SIZE > 27) { t[n++] = v27; }
			if(SIZE > 28) { t[n++] = v28; }
			if(SIZE > 29) { t[n++] = v29; }
			if(SIZE > 30) { t[n++] = v30; }
			if(SIZE > 31) { t[n++] = v31; }
			if(SIZE > 32) { t[n++] = v32; }
			if(SIZE > 33) { t[n++] = v33; }
			if(SIZE > 34) { t[n++] = v34; }
			if(SIZE > 35) { t[n++] = v35; }
			if(SIZE > 36) { t[n++] = v36; }
			if(SIZE > 37) { t[n++] = v37; }
			if(SIZE > 38) { t[n++] = v38; }
			if(SIZE > 39) { t[n++] = v39; }
			if(SIZE > 40) { t[n++] = v40; }
			if(SIZE > 41) { t[n++] = v41; }
			if(SIZE > 42) { t[n++] = v42; }
			if(SIZE > 43) { t[n++] = v43; }
			if(SIZE > 44) { t[n++] = v44; }
			if(SIZE > 45) { t[n++] = v45; }
			if(SIZE > 46) { t[n++] = v46; }
			if(SIZE > 47) { t[n++] = v47; }
			if(SIZE > 48) { t[n++] = v48; }
			if(SIZE > 49) { t[n++] = v49; }
			if(SIZE > 50) { t[n++] = v50; }
			if(SIZE > 51) { t[n++] = v51; }
			if(SIZE > 52) { t[n++] = v52; }
			if(SIZE > 53) { t[n++] = v53; }
			if(SIZE > 54) { t[n++] = v54; }
			if(SIZE > 55) { t[n++] = v55; }
			if(SIZE > 56) { t[n++] = v56; }
			if(SIZE > 57) { t[n++] = v57; }
			if(SIZE > 58) { t[n++] = v58; }
			if(SIZE > 59) { t[n++] = v59; }
			if(SIZE > 60) { t[n++] = v60; }
			if(SIZE > 61) { t[n++] = v61; }
			if(SIZE > 62) { t[n++] = v62; }
			if(SIZE > 63) { t[n++] = v63; }
			if(SIZE > 64) { t[n++] = v64; }
			H_ASSERT(n == SIZE);
		}

		/**
		 * Non-const array access operator.
		 *
		 * @param i Array index.
		 */
		inline T &operator[](int i) {
			Validate(i);
			return t[i];
		}

		/**
		 * Const array access operator.
		 *
		 * @param i Array index.
		 */
		inline const T &operator[](int i) const {
			Validate(i);
			return t[i];
		}

		/**
		 * This function returns a handle to the wrapped C-array. It
		 * is dangerous and only defined for legacy code.
		 */
		T* GetPtr() {
			return t;
		}

		/**
		 * This function returns a const handle to the wrapped
		 * C-array.
		 */
		const T* GetPtr() const {
			return t;
		}

	private:
		/**
		 * The wrapped C-array.
		 */
		T t[SIZE];

		/**
		 * Check if the array index is valid.
		 *
		 * This is a Nop in non-debug mode.
		 */
		inline void Validate(int i) const {
			i = i; // Avoid unused parameter warning in non-debug mode.
#ifndef NDEBUG
			if(i < 0 || i > SIZE - 1) {
				LOG << "array bound violation. index: " << i << ", valid range: "
					<< "0.." << SIZE - 1
					<< std::endl;
				H_ASSERT(false);
			}
#endif
		}
	};

} // namespace hossa

#endif



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.