[SOLVED] Valgrind errors with std::vector
Greetings.
I've been working on a polynomial calculator. I was very happy to have finally finished my implementation of Newton's Tangent Method as well as Ruffini's Rule. Together, I intended to use them to find all the zeros of a function.
However, as I started combining the two, I realized that removing a cout statement or adding it in a function would cause the said function to produce different outputs. This made me think that I was seeing either stack or heap corruption.
So I opened up valgrind and I was astonished with the amount of errors I had.
The first error seems the most important one, and the one that leads to several others. But to show it to you, I have to place part of the code here.
I first have a class named Term:
Code:
class Term {
public:
// Methods...
unsigned int exponent;
double quocient;
protected:
private:
};
The Term class doesn't seem to have any problems at all and those are its only members: a uint32 named exponent and a double named quocient.
Next is the Polynomial class:
Code:
class Polynomial {
public:
Polynomial();
bool addTerm(Term term);
bool add0Term(unsigned int exponent);
//Some other methods
std::vector<Term> terms;
protected:
private:
};
This is where everything gets ruined. I have the member terms which is std::vector<Term>.
During the implementation of addTerm and add0Term (both with the same code, the difference lies just in adding a zero-quocient Term), I check for an empty list as follows:
Code:
bool Polynomial::addTerm(Term term) {
bool anybigger = false;
////
// If this is the first, just push it.
//
if(terms.size()==0) {
terms.push_back(term);
return true;
}
//More code...
Now, the first valgrind error happens at exactly terms.push_back(term), here's the error:
Quote:
==30949== Invalid read of size 4
==30949== at 0x804990F: Polynomial::addTerm(Term) (main.cxx:165)
==30949== by 0x804AD11: main (main.cxx:517)
==30949== Address 0x4037474 is 0 bytes after a block of size 12 alloc'd
==30949== at 0x4008390: operator new(unsigned int) (vg_replace_malloc.c:214)
==30949== by 0x804C4A1: __gnu_cxx::new_allocator<Term>::allocate(unsigned int, void const*) (new_allocator.h:89)
==30949== by 0x804C211: std::_Vector_base<Term, std::allocator<Term> >::_M_allocate(unsigned int) (stl_vector.h:140)
==30949== by 0x804BBC6: std::vector<Term, std::allocator<Term> >::_M_insert_aux(__gnu_cxx::__normal_iterator<Term *, std::vector<Term, std::allocator<Term> > >, Term const&) (vector.tcc:322)
==30949== by 0x804B494: std::vector<Term, std::allocator<Term> >::push_back(Term const&) (stl_vector.h:741)
==30949== by 0x80498A2: Polynomial::addTerm(Term) (main.cxx:153)
==30949== by 0x804ACE7: main (main.cxx:516)
And the sequence of calls is presented here:
Code:
//main.cxx:516
Term term1(4,-5);
//... more code
Polynomial poly;
//... more code
poly.addTerm(term1);
Code:
//main.cxx:153
bool Polynomial::addTerm(Term term) {
//More code...
////
// If this is the first, just push it.
//
if(terms.size()==0) {
terms.push_back(term);
return true;
}
//More code...
I even ported my application to use the simple vector class I made some time ago and which didn't implement iterators or standard allocators. Even with it, I reached this error, so I think it is safe to admit that *I* am doing something wrong...but what is it? What's wrong with pushing back a term? I should note that even adding a terms.reserve(1); before would make valgrind complain at that same line, so the problem isn't with me adding the term, but it seems somehow related to how terms was created/constructed?
Can somebody help me understand this, please? Otherwise I'll just dump vectors and good with good old arrays, memcpy(), memmove(), new and delete.
Maybe I forgot to implement some kind of important constructor and it defaulted to a buggy one? I doubt that, though...
Thanks,
Jorl17