views:

121

answers:

4

I am just starting out C++, so sorry if this is a dumb question. I have a class Braid whose members are vectors. I have not written an assignment operator. When I do a lot of assignments to an object of the type Braid, I run into memory issues :-

 0  0xb7daff89 in _int_malloc () from /lib/libc.so.6
#1  0xb7db2583 in malloc () from /lib/libc.so.6
#2  0xb7f8ac59 in operator new(unsigned int) () from /usr/lib/libstdc++.so.6
#3  0x0804d05e in __gnu_cxx::new_allocator<int>::allocate (this=0xbf800204, __n=1)
    at /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../../include/c++/4.4.3/ext/new_allocator.h:89
#4  0x0804cb0e in std::_Vector_base<int, std::allocator<int> >::_M_allocate (this=0xbf800204, __n=1)
    at /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../../include/c++/4.4.3/bits/stl_vector.h:140
#5  0x0804c086 in _Vector_base (this=0xbf800204, __n=1, __a=...)
    at /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../../include/c++/4.4.3/bits/stl_vector.h:113
#6  0x0804b4b7 in vector (this=0xbf800204, __x=...)
    at /usr/lib/gcc/i686-pc-linux-gnu/4.4.3/../../../../include/c++/4.4.3/bits/stl_vector.h:242
#7  0x0804b234 in Braid (this=0xbf800204) at braid.h:13
#8  0x080495ed in Braid::cycleBraid (this=0xbf8001b4) at braid.cpp:191
#9  0x080497c6 in Braid::score (this=0xbf800298, b=...) at braid.cpp:251
#10 0x08049c46 in Braid::evaluateMove (this=0xbf800468, move=1, pos=0, depth=2, b=...)

I suspect that these memory issues are because the vectors are getting resized. What I want to know is whether objects of type Braid automatically expand when its members expand? the code I am writing is really long so I will post the section which is causing the problems. Here is the relevant section of the code :-

class Braid 
{
private :
  vector<int> braid; //Stores the braid.  
  int strands;
  vector < vector<bool> > history; 
  vector < vector<bool> > CM;    
public :
  Braid () : strands(0) {}
  Braid operator * (Braid);
  Braid* inputBraid(int,vector<int>);
  int printBraid();
  int printBraid(vector<vector<int>::iterator>);
  vector<int>::size_type size() const;
               .....
               .....
}

Here is the function which causes the issue :-

int Braid::evaluateMove(int move,int pos,int depth,Braid b)
{
 int netscore = 0;
 Braid curr(*this);
 curr = curr.move(move,pos);
 netscore += curr.score(b);

 while(depth > 1)
 {
   netscore += curr.evaluateMove(1,0,depth,b);
   netscore += curr.evaluateMove(2,0,depth,b);
   for(int i = 0; i < braid.size();++i)
   {
    netscore += curr.evaluateMove(3,i,depth,b);
    netscore += curr.evaluateMove(4,i,depth,b);
    netscore += curr.evaluateMove(5,i,depth,b);
    curr = curr.cycleBraid();
    netscore += curr.evaluateMove(6,0,depth,b);
   }
   --depth;
 }
 return netscore;
}
+3  A: 

quick read: Braid curr(*this); causes a copy. Can't you use a pointer to the Braid?

PoweRoy
The function cycleBraid modify's the Braid, so I make a temporary copy.
I would +1 if I had votes left.
Billy ONeal
@Billy: Did it for you. @user: `curr = curr.move(move,pos);` looks like overkill, blowing away a `Braid` outright. This code looks like it needs some references and pointers and refactoring, but I can't tell what `Braid` is trying to achieve. Is it some kind of arcane game theory stuff?
Mike DeSimone
@Mike I am trying to implement the Braid group http://en.wikipedia.org/wiki/Braid_group
+1  A: 

On an unrelated point, you probably do not want:

 vector<bool>

as vector<bool> is a template specialisation which you should only use if you really, really know what you are doing. Consider vector <char> or deque<bool> instead.

anon
I think you meant "consider `vector<char>/vector<int>` or something and `deque<bool>` above... Do I have that right?
Billy ONeal
@Billy, no, I meant what I said. `deque<bool>` is not a specialisation and has almost all the features that `vector<bool>` should have had.
anon
What exactly do you mean?
Michael Daum
Hmm, interesting downvote.
anon
@Neil Butterworth: Sorry -- I saw a pre-edit version where it just said "consider vector or deque" without specifying the template argument. And no, I did not downvote.
Billy ONeal
Sorry, when I down voted it said "as vector is a template specialisation....Consider vector or deque instead"My bad.
Michael Daum
I'm inclined to disagree with the "do not want". Considering the fact that you've got 2 vectors of vectors of bools, the benefit of `vector<bool>` may outweigh its unusual non-generic nature
MSalters
+3  A: 

Another problem :

while(depth > 1)
{
  netscore += curr.evaluateMove(1,0,depth,b);
  ....
  --depth;
}

causes endless recursion when depth >1

a1ex07
Oh, I am not the only one it bothered then :)
Matthieu M.
Thanks a lot! Changed it in the relevant places to depth-1. Dumb mistake but I think I am learning a lot from the comments.
+3  A: 

Am I the only remarking a Stack Overflow there ?

I colored out the useless bits (for the purpose of the demo)

int Braid::evaluateMove(int move,int pos,int depth,Braid b)
{
  #int netscore = 0;
  #Braid curr(*this);
  #curr = curr.move(move,pos);
  #netscore += curr.score(b);

  while(depth > 1)
  {
    netscore += curr.evaluateMove(1,0,depth,b);
    #netscore += curr.evaluateMove(2,0,depth,b);
    #for(int i = 0; i < braid.size();++i)
    #{
    #  netscore += curr.evaluateMove(3,i,depth,b);
    #  netscore += curr.evaluateMove(4,i,depth,b);
    #  netscore += curr.evaluateMove(5,i,depth,b);
    #  curr = curr.cycleBraid();
    #  netscore += curr.evaluateMove(6,0,depth,b);
    #}
    --depth;
  }
  return netscore;
}

Now if depth is superior to 1... oups

Let's say I do:

  • Braid b; b.evaluateMove(1,0,2,b);
  • it invokes curr.evaluateMove(1,0,2,b);
  • which invokes curr.evaluateMove(1,0,2,b);
  • which ...

Well, the system might run out of memory.

Note: why does evaluateMove both copy this and ask for a copy of Braid (parameter b) ? I'd check my score method if I was you.

Matthieu M.
Not just you :)
a1ex07