Marshal.FreeHGlobal COMException

Dan

New member
Joined
Jan 6, 2014
Messages
1
Programming Experience
5-10
Hi All,

I am fairly new to C# (From a VB.NET background). I have to edit some code left over from a previous person and I am running into a COMException error freeing memory. I have included the the complete function below and a screenshot of the error. Any help would be appreciated.

06-01-2014 13-01-09.png

C#:
public static Size CalculateTextExtent(string text, Font font, int maximumWidth, Graphics graphics, out int maximumCharactersThatFit, out int[] stringWidths)        {
            maximumCharactersThatFit = 0;
            stringWidths = new int[0];


            if ((text == null) || (text.Length == 0)) return Size.Empty;


            IntPtr tmp_oHdc = graphics.GetHdc();
            IntPtr tmp_oFont = font.ToHfont();
            IntPtr tmp_oPrevSelectedFont = NativeMethods.SelectObject(tmp_oHdc, tmp_oFont);


            NativeMethods.SIZE tmp_oSIZE = new NativeMethods.SIZE(0, 0);
            IntPtr tmp_oStringWidthsArray = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * text.Length);
            Int16 tmp_iMaxCharsTatFit = 0;
            try
            {
                NativeMethods.GetTextExtentExPoint(
                    tmp_oHdc,
                    text,
                    text.Length,
                    maximumWidth,
                    ref tmp_iMaxCharsTatFit,
                    tmp_oStringWidthsArray,
                    ref tmp_oSIZE);
            }
            finally
            {
                NativeMethods.SelectObject(tmp_oHdc, tmp_oPrevSelectedFont);
                NativeMethods.DeleteObject(tmp_oFont);
                graphics.ReleaseHdc(tmp_oHdc);
            }


            maximumCharactersThatFit = tmp_iMaxCharsTatFit;
            Size tmp_oResultSize = new Size(tmp_oSIZE.cx, tmp_oSIZE.cy);
            stringWidths = new int[maximumCharactersThatFit];
            Marshal.Copy(tmp_oStringWidthsArray, stringWidths, 0, stringWidths.Length);
            Marshal.FreeHGlobal(tmp_oStringWidthsArray);


            return tmp_oResultSize;
        }
 
Hard to say. That's not newb friendly code at all. It's calling native c++ functions. It could be that your platform is not supported.
Marshal.FreeHGlobal Method (System.Runtime.InteropServices)
Platforms


Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

If you think it should work on your platform. try adding a catch to the try block and print if any results.

C#:
try {
    ...the same code
} 

// add this. 
catch (Exception e) {
    Console.WriteLine(e.ToString() + "\n" + e.Message);
}

finally {
   ..same code
}

Or just coment out the try finally blocks and see if a different exception is thown.

The exception you are getting is when you try to free the memory allocated by
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * text.Length);

the correct code may be
Marshal.AllocHGlobal(Marshal.SizeOf(Marshal.SystemDefaultCharSize * text.Length);

but int should be more than big enough on any platform since the size of an int (4) is bigger than a char (2)

I would try to allocate and free memory using another means. I'm unfamiliar with dynamic memory allocation in c#. It's not the typical c# way of doing things afik.
Also I don't fully understand what the code does but since no one else is answering I thought I'd give a crack at it. Maybe something I said will point you in the right direction
 
Back
Top Bottom