Re: Vector is deleted after resize()
xman <cshinyee@gmail.com> wrote in message ...
The codes below basically builds a binary tree. It runs well on Intel
compiler. However, when I use gcc 4.2.0, the assignment to b[i].right
causes segmentation fault. Tracing with valgrind reveals that the
particular memory address was deleted during push_back().
If I change the assignments to
int x = build_recursive(n-1);
int y = build_recursive(n-1);
b[i].left = x;
b[i].right = y;
there is no segmentation fault anymore. It seems to me the original
code has the b[i] value cached, hence, during the assignment to
b[i].right, it uses old b[i] which may be invalidated after
push_back() due to resize.
Any ideas? Compiler problems? or non-trivial bugs? Thanks.
#include <vector>
using std::vector;
class A {
public:
int left;
int right;
};
class B{ public:
void build(int n){
b.clear();
If you also want to 'reset' capacity (.clear() doesn't):
vector<A>.swap( b ); // b.clear() not needed
next_index = 0;
int root = build_recursive(n);
Do you do something with 'root'?
Else just:
build_recursive( n ); // ignore return.
}
int build_recursive(int n) {
int i = get_next_index();
if (n > 0) {
b[i].left = build_recursive(n-1);
b[i].right = build_recursive(n-1);
}
return i;
}
This won't fix the problem, but might help you find it faster (next time):
int build_recursive(int n) {
int i = get_next_index();
if (n > 0) {
try{
b.at( i ).left = build_recursive( n-1);
b.at( i ).right = build_recursive( n-1);
}
catch( std::out_of_range const &Oor){
std::cerr << "caught Oor=" << Oor.what() << std::endl;
std::cerr<<"i="<<i<<" n="<<n<<std::endl;
} // catch(oor)
} // if(n)
return i;
}
// note: this is for 'testing'. You would remove the try-catch for final.
// You could put the try-catch in main() (still use the '.at()' though).
// recursion is a bitch! <G>
// I'm not sure how try{} reacts in a recursive call, so, 'grain-of-salt'...
int get_next_index(void) {
A a;
b.push_back(a);
int index = next_index++;
return index;
}
int next_index;
vector<A> b;
};
int main(int argc, char* argv[]){
B tree;
tree.build(14);
return 0 ;
}
You do know you can set the vector size in constructor, don't you?
class B{ public:
B( std::size_t size ): b( size ){}
// .....
vector<A> b;
};
Just some ideas for you to think about.
--
Bob R
POVrookie