[computer-go] C++ pointer question
Adrian Grajdeanu
adriang0 at cox.net
Tue Aug 8 18:53:44 PDT 2006
Finally a question where I can help...
The solution suggested by Berk Ozbozkurt points to probably the fastest
way. The devil is in the details though. One such class (with pointers
allocated on constructor and deallocated on destructor) needs a copy
constructor, as the default one provided by the compiler is inadequate.
And when writing this copy constructor you'd need to be careful. There
are a few options here:
1. Forbid copying. For this provide an empty body _private_ copy
constructor and similarly an empty body _private_ assignment operator.
Thus the compiler won't allow you to code the mistake of accidentally
copying BitBoard objects.
2. Implement transfer semantics. Provide copy constructor and assignment
operator that takes over the allocated chunk of memory. Like so:
BitBoard::BitBoard(const BitBoard &board) :
bits(board.bits)
{
board.bits = 0;
}
const BitBoard &BitBoard::operator = (const BitBoard &board)
{
if (this == &board) return; // very important!!!
if (bits) delete [] bits;
bits = board.bits; board.bits = 0;
}
3. Use reference counting. The idea is that multiple objects
collectively own the bits array. When the refcount reaches zero only
then it is deallocated. For this though, things can get very hairy. I
suggest if you don't have the experience in C++ you do not attempt it.
Instead seek an already made reputable refcounted autopointer
implementation and use that (boost library comes to mind!). If your app
is muti-threaded, pay attention that the autopointer is implemented in a
thread-safe manner.
However if Berk Ozbozkurt's suggestion cannot be applied, then typically
a fast copy can be achieved with:
memcpy(&bits[0], &temp.bits[0], board_width * sizeof(bits[0])).
(or something like it. May need to play with the count of bytes
to copy due to extra padding introduced by alignment - if any!)
(I used '&bits[0]' in case the [] is overloaded. If it is not, then
simply 'bits' will suffice.)
That is provided you're not copying objects that have non-trivial
constructor/destructor; from your code it seems you're copying ints (or
some like them), so this should be no problem.
Yet a 3rd alternative, that avoids all the hassles is to give up
low-level management of arrays (and pointers) and use the std::vector
class. It is designed to work in the most efficient possible way. I have
had very good experience with it as it has close to zero overhead. The
only way to make it more efficient is to hardcode at compile time the
size of the arrays, and use memcpy like above.
As a general note on the std::vector, do stay away from
std::vector<bool> - it is ... iffy, unless you understand it pretty
well... All other vectors are peachy.
All the best,
Adrian
Peter Drake wrote:
> Okay, I've got this method in my BitBoard class:
>
> void dilate() // Expand to include all adjacent points
> {
> BitBoard temp;
> temp.bits[0] = bits[0] | (bits[0] << 1) | (bits[0] >> 1) | bits[1];
> temp.bits[board_width - 1] = bits[board_width - 1] | (bits[board_width -
> 1] << 1)
> | (bits[board_width - 1] >> 1) | bits[board_width - 2];
> for (unsigned row = 1; row < board_width - 1; row++) {
> temp.bits[row] = bits[row] | (bits[row] << 1) | (bits[row] >> 1) |
> bits[row - 1] | bits[row + 1];
> }
> for (unsigned row = 0; row < board_width; row++) {
> bits[row] = temp.bits[row];
> }
> }
>
> Is there some way to avoid that second for loop? I tried "this = temp"
> and "*this = *temp", but the compiler isn't happy with either.
>
> Thanks,
>
> Peter Drake
> Assistant Professor of Computer Science
> Lewis & Clark College
> http://www.lclark.edu/~drake/
>
>
>
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> computer-go mailing list
> computer-go at computer-go.org
> http://www.computer-go.org/mailman/listinfo/computer-go/
More information about the computer-go
mailing list