La bla bla
La bla bla

Reputation: 8708

Understanding Valgrind's output

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

Answers (2)

coelhudo
coelhudo

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

Karoly Horvath
Karoly Horvath

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

Related Questions