2

What does this error in Valgrind mean? I've looked at a lot of other posts but I still don't understand what the error actually means. Is there a problem with my Dragon destructor function?

==48500== Invalid read of size 8
==48500==    at 0x40AF66: Dragon::~Dragon() (in /u3/nsah/cs246/1149/a5/cc3k/cc3k/test)
==48500==    by 0x40AFDB: Dragon::~Dragon() (in /u3/nsah/cs246/1149/a5/cc3k/cc3k/test)
==48500==    by 0x406841: Floor::deleteAll() (in /u3/nsah/cs246/1149/a5/cc3k/cc3k/test)
==48500==    by 0x4022D8: Floor::~Floor() (in /u3/nsah/cs246/1149/a5/cc3k/cc3k/test)
==48500==    by 0x401EE1: main (in /u3/nsah/cs246/1149/a5/cc3k/cc3k/test)
==48500==  Address 0x5a1d130 is 0 bytes inside a block of size 40 free'd
==48500==    at 0x4C2A4BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==48500==    by 0x40A7B3: Treasure::~Treasure() (in /u3/nsah/cs246/1149/a5/cc3k/cc3k/test)
==48500==    by 0x40671B: Floor::deleteAll() (in /u3/nsah/cs246/1149/a5/cc3k/cc3k/test)
==48500==    by 0x4022D8: Floor::~Floor() (in /u3/nsah/cs246/1149/a5/cc3k/cc3k/test)
==48500==    by 0x401EE1: main (in /u3/nsah/cs246/1149/a5/cc3k/cc3k/test)

EDIT: This is what my Dragon class looks like:

#include "dragon.h"
#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

Dragon::Dragon(Item *hoard) {
    // initalizes some variables
    treasureHoard = hoard;
}

Dragon::~Dragon(){
    treasureHoard->deadDragon();
}

// some functions

EDIT: Basically my code does this:

D *ptr=new D();
// some code …
if (ptr->isDead()) {
    delete ptr;
    ptr = NULL;
}
// some code

// at the end of the program: 
if (ptr) {   // <<< is this causing the error?
    delete ptr;
    ptr = NULL;
}
Niveda Sah
  • 23
  • 1
  • 1
  • 4

1 Answers1

2

I think the valgrind message is pretty clear:

==48500==  Address 0x5a1d130 is 0 bytes inside a block of size 40 free'd

There is a block of data which was "free'd" (in C++ most likely actuall `delete'd) and which is still being accessed. More precisely, one word of 8 bytes right at the start of the freed block of memory which started out to be of size 40 is being read.

That is, you effectively have code doing the moral equivalent of this:

T* ptr = new T; // allocator memory of an object of size 40
...
delete ptr;           // release the memory
...
X value = ptr->start; // read the first word of the data

(clearly, the type, member, and variable names will be different in code but that's roughly what is happening)

Here is a complete program replicating the problem (although with a simpler stack):

struct foo {
    double values[5];
};

int main()
{
    foo* ptr = new foo();
    delete ptr;
    double x = ptr->values[0];
    return x;
}
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • Once I delete my pointer, I just check to see if it exists before ending the program. Do you thing that is causing the error? I am pretty sure that I do not try to access the deleted pointer at any other time. (Edited my main question) – Niveda Sah Nov 29 '14 at 17:27
  • Although reading the pointer itself is undefined behavior (once a pointer is deleted you can only assign to pointers holding this value) I doubt that reading the is what valgrind reports. Something is probably reading a value the pointer points to. Looking at the code and the stack trace I'd guess that object you destroy is already deleted. – Dietmar Kühl Nov 29 '14 at 19:11