Reputation: 8708
I'm writing a project for university. It's all done, passes all the tests, runs fine, but Valgrind tells me this:
==8059== Invalid read of size 8
==8059== at 0x406E4E: RegPoly::getCurrentCoefficient() const (RegPoly.cpp:59)
==8059== by 0x403368: MyPoly::operator+(MyPoly const&) const (MyPoly.cpp:281)
==8059== by 0x403A6D: MyPoly::operator+=(MyPoly const&) (MyPoly.cpp:354)
==8059== by 0x401E20: main (DemoPoly.cpp:50)
==8059== Address 0x5953f50 is 0 bytes after a block of size 16 alloc'd
==8059== at 0x4C27297: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8059== by 0x4060CD: __gnu_cxx::new_allocator<double>::allocate(unsigned long, void const*) (new_allocator.h:92)
==8059== by 0x405934: std::_Vector_base<double, std::allocator<double> >::_M_allocate(unsigned long) (in /a/fr-05/vol/home/stud/lablabla/CppLab/Ex3/DemoPoly)
==8059== by 0x407355: double* std::vector<double, std::allocator<double> >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > > >(unsigned long, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >, __gnu_cxx::__normal_iterator<double const*, std::vector<double, std::allocator<double> > >) (stl_vector.h:1052)
==8059== by 0x40700E: std::vector<double, std::allocator<double> >::operator=(std::vector<double, std::allocator<double> > const&) (vector.tcc:167)
==8059== by 0x406C5D: RegPoly::RegPoly(RegPoly const&) (RegPoly.cpp:19)
==8059== by 0x4031DB: MyPoly::operator=(MyPoly const&) (MyPoly.cpp:249)
==8059== by 0x403B58: MyPoly::operator*=(MyPoly const&) (MyPoly.cpp:364)
==8059== by 0x401DB6: main (DemoPoly.cpp:44)
The lines:
44 - p3 *= p2; // both are MyPoly objects
50 - p3 += p1;
I kind of understand that it means that I'm trying to read from a memory that has been changed (?), but I couldn't understand why. I could post the relevant code, only, I'm not sure which part, as it would make the question messy. I can paste relevant parts, just tell me what you need.
Here's the code:
MyPoly& MyPoly::operator *=(const MyPoly& rhs)
{
*this = *this * rhs; // 364
return *this;
}
// ===================
case PolyInterface::REG:
{
RegPoly *tempReg = dynamic_cast<RegPoly*>(rhs.p_PolyBody); // rhs is an interface, hence the dynamic cast
if (tempReg != NULL)
{
p_PolyBody = new RegPoly(*tempReg); // 249. p_PolyBody is a pointer stored in MyPoly. points to RegPoly object
}
break;
}
// ===================
RegPoly::RegPoly(RegPoly const& other)
{
gCurrentRank = 0;
gData = other.gData; // 19. gData is a vector<double>
_isZeroPoly = other._isZeroPoly;
}
// ===================
double RegPoly::getCurrentCoefficient() const
{
return *gDataIterator; // 59. vector<double>::const_iterator
}
// ===================
newPolyValues.push_back(
p_PolyBody->getCurrentCoefficient() + rhs.p_PolyBody->getCurrentCoefficient());
// 281.
I'm also getting this when getCurrentCoefficient()
returns gData[gCurrentRank]
, meaning that it's something with the location of gData itself, right?
RegPoly:
std::vector<double> gData;
std::vector<double>::iterator gDataIterator;
int gCurrentRank;
bool _isZeroPoly; // Inherited from the interface
Upvotes: 0
Views: 487
Reputation: 5080
The problem is on RegPoly.cpp:59, not in DemoPoly.cpp:50.
It is stated that you had allocated 16 bytes, but it is trying to read 8 bytes beyond your allocation.
See this: 4.2. Explanation of error messages from Memcheck
Probably you are trying to access an invalid iterator. A const iterator just means that you are not able use this iterator to modify a value inside a container.
A brief explanation related to invalid iterators.
Upvotes: 1
Reputation: 96258
Trust Valgrind. It almost always shows existing problems.
Here is how you read the message:
RegPoly::getCurrentCoefficient() const (RegPoly.cpp:59)
tried to read from a memory location it shouldn't have read, because it doesn't belong to your app (wasn't allocated, non-stack, etc...).
This invalid address was just beyond the space that was allocated with the new operator, used in your RegPoly
copy constructor (and you can see the whole backtrace that created that call).
I don't see that your copy constructor copies gDataIterator
.
Upvotes: 1