4

If I use delete or ::delete I get a C++ exception. Of course I can just let it go without deletion and it is fine, but that memory leak is going to build up very quickly.

My code is as follows: (including anything related to gdi+ that may be relevant)

#include <windows.h>

#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif

namespace Gdiplus
{
    using std::min;
    using std::max;
}
#include <gdiplus.h>
#pragma comment (lib,"Gdiplus.lib")

namespace Infra
{
    namespace Color
    {
        //more app code


        void CrashingMethod(...)
        {
            Gdiplus::Bitmap* bitmap = Gdiplus::Bitmap::FromFile(PNG_PATH);

            //read bitmap
            int qpWidth = frameWidth / 16;
            Gdiplus::Color color = Gdiplus::Color();

            for (unsigned int y = 0, qy = (frameHeight / 16) - 1; y < frameHeight; y += 16, qy--)
            {
                for (unsigned int x = 0, qx = 0; x < frameWidth; x += 16, qx++)
                {
                    bitmap->GetPixel(x, y, &color);

                    byte red = color.GetRed();

                    //do stuff with the red channel

                }
            }

            delete bitmap; //this line will randomly crash. Not always, not in all machines
            bitmap = NULL;
        }
    }


    }
}

What is the right way to deallocate this one? I know there are issues with deleting gdi+ bitmaps, but the solution of doing ::delete doesn't make it any better. Unlike solutions I have seen, I am not using new to create the bitmap, but "FromFile".

Also, as you can see, I am not using I am not using "namespace Gdiplus" so the namespace is not in the scope and I need to refer to it explicitly(which may change things).

cloudraven
  • 2,484
  • 1
  • 24
  • 49
  • Wait, you're *not* using the `Gdiplus` namespace with your code littered with `Gdiplus::` and including ``? What are you using instead? If you are certain you're not using the namespace, you'll have to look at what you are using instead. – andlabs Dec 01 '15 at 05:18
  • 2
    Gdi+ objects - such as Bitmap - that derive from GdiPlusBase are intended to be managed via new and delete. It seems more likely that you have a memory overrun elsewhere that is corrupting the heap, causing the random crash on deallocation. – Chris Becke Dec 01 '15 at 06:14
  • andlabs. I should rephrase. I am not using "namespace Gdiplus" so the namespace is not in the scope and I need to refer to it explicitly. WIll fix it in the description – cloudraven Dec 01 '15 at 07:14
  • Chris, I have read that gdiplus defines its own new and delete operators. I have seen people having issues with them. I thought perhaps this problem was related to that. Do you know which version of the operator I should use? – cloudraven Dec 01 '15 at 07:17
  • Setting `bitmap` to `NULL` immediately before it leaves scope seems pointless. The compiler will surely optimise that away in any case. – David Heffernan Dec 01 '15 at 09:23
  • 1
    I'm somewhat sure, that you do not get a C++ exception, but rather a failed assertion, or SEH exception (additional details would be helpful). This happens when `new` and `delete` operate on different heaps, for example (see [Potential Errors Passing CRT Objects Across DLL Boundaries](https://msdn.microsoft.com/en-us/library/ms235460.aspx)). To prevent this, your application must dynamically link against the same CRT that is used by GDI+. Unrelated, but if you don't want `min`/`max` to be defined as macros, `#define NOMINMAX` prior to including *Windows.h*. – IInspectable Dec 01 '15 at 09:25

1 Answers1

2

The way that you create the bitmap object, and delete it, is correct. You have another defect in your program that is responsible for heap corruption. You need to find that defect and fix it.

Heap corruptions can be confusing. The defect can be in one part of the code, but the runtime error only occurs in a different, often unrelated, part of the code. They are hard to debug and you might find a tool useful to help this: Is there a good Valgrind substitute for Windows?

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • It was heap corruption and it is actually in that loop in the code. qy was going below 0, being unsigned going to a high value, larger than an array I was addressing with it. Thanks – cloudraven Dec 06 '15 at 11:17