Valgrind Invalid Read Error

262 views Asked by At

I have been unable to pinpoint the exact reason for my Valgrind error:

==3868== Invalid read of size 2
==3868==    at 0x100001F1F: Shrinker::Execute() (in ./proj4B)
==3868==    by 0x1000029CD: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==  Address 0x100c12040 is 0 bytes inside a block of size 7,201,152 free'd
==3868==    at 0x10000D94F: free (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==3868==    by 0x100001BD5: PNMreader::Execute() (in ./proj4B)
==3868==    by 0x100001954: Source::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)
==3868==    by 0x10000299E: Filter::Update() (in ./proj4B)
==3868==    by 0x100001819: Image::Update() const (in ./proj4B)

I'm thinking it's due to my nested loop in Shrinker::Execute() and/or it's destructor:

void Shrinker::Execute() {
    int inWidth = 0, inHeight = 0, maxVal = 255;
    int halfWidth = 0, halfHeight = 0;

    inWidth = img1->GetWidth();
    inHeight = img1->GetHeight();

    halfWidth = inWidth / 2;
    halfHeight = inHeight / 2;

    buffer = (Pixel *) malloc(sizeof(Pixel)*halfWidth*halfHeight);

    int in = 0, out = 0;
    for (int i = 0; i < halfHeight; i++) {
        for (int j = 0; j < halfWidth; j++) {
            in = i*2*inWidth+j*2;
            out = i*halfWidth+j;
            buffer[out] = img1->GetPixels()[in];
        }
    }

    img.ResetSize(halfWidth, halfHeight);
    img.SetMaxVal(maxVal);
    img.SetPixels(buffer);

}   // end Shrinker::Execute()

I've attempted making every minor adjustment I could think of to both the nested loop and the malloc in Shrinker, to no avail. It's destructor frees the buffer and sets it to NULL. Any guidance would be greatly appreciated.

2

There are 2 answers

1
Tuan Tu On

Actually, I don't know the purpose of your code. However, maybe you use wrong parameter in below code:

in = i*2*inWidth+j*2;

It should be:

in = i*2*halfwidth+j*2;

I think.

0
Michael Anderson On

I'm guessing here, but since its an access into a block that has been previously free'd - something is destroying the buffer allocated in Shrinker::Execute - if the only place that is free'd is your destructor, then you've probably got a bad (possibly temporary) copy created of your Shrinker - this would happen if you returned a Shrinker object from a function for example.

You need to ensure that you've either prevented copies from getting created or correctly implemented the copy constructor and assignment operators.