Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3420770
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T06:02:43+00:00 2026-05-18T06:02:43+00:00

Short version: Could passing the handle from GlobalAlloc(GMEM_MOVEABLE, Size) to Marshal.PtrToStructure() and Marshal.FreeHGlobal() cause

  • 0

Short version:

Could passing the handle from GlobalAlloc(GMEM_MOVEABLE, Size) to Marshal.PtrToStructure() and Marshal.FreeHGlobal() cause memory corruption?

Long version:

I’m using Windows Global memory allocation to pass a data structure back and forth between a Delphi and C# application (the fact that it’s Delphi isn’t really significant to this question, because it’s just Win32 API calls).

On the Delphi side, I pass in a record, it allocates the space, locks the memory, copies the structure into memory, and the unlocks the memory:

function MarshalRec(SourceRec: TInteropItemRec): THandle;
var
  Size: integer;
  Buffer: Pointer;
begin
  Size := sizeof(SourceRec);
  result := GlobalAlloc(GMEM_MOVEABLE and GMEM_ZEROINIT, Size);
  Buffer := GlobalLock(result);
  try
    CopyMemory(Buffer, @SourceRec, Size);
  finally
    GlobalUnlock(result);
  end;
end;

On the C# side, it gets that THandle (which is basically an unsigned int) into an IntPtr and uses Marshal.PtrToStructure to copy the data into the C# structure:

public void FromMemory(IntPtr Source)
{
    Marshal.PtrToStructure(Source, this);
    Marshal.FreeHGlobal(Source);
}

The problem I’m running into, is very rarely (as in 4 times over 6 months for me), the whole application goes down (This application has encountered an error and must close). If I try to pause execution in Visual Studio, I get “A fatal error has occurred and debugging needs to be terminated. For more details, please see the Microsoft Help and Support web site. HRESULT=0x80131c08.”

Anyway, we managed to get a couple logs of it happening, and in both cases, it showed a recent call to that “MarshalRec” function above, a few other function calls, and then some processing of Windows messages on the event loop on the Delphi thread (yeah, it has its own thread and event loop to deal with a time sensitive device driver).

So my suspicion is falling on the GMEM_MOVEABLE flag to GlobalAlloc. I couldn’t find anything in the Marshal class that does the GlobalLock and GlobalUnlock stuff, so I had assumed it was handled internally by PtrToStructure().

Does PtrToStructure deal properly with a handle, or does it need an actual pointer obtained from GlobalLock()? Is it possible that in very rare cases, Windows happens to move the memory I allocated, which means I need to call GlobalLock() to get an actual pointer to pass in? That FreeHGlobal is actually freeing something it shouldn’t have, which brings down the whole app the next time that resource is accessed?

And if so, should changing the GMEM_MOVABLE to GMEM_FIXED prevent this from happening again? Or do I need to DllImport GlobalLock() and GlobalUnlock()?

I’m tempted to just blindly make those changes, but given the non-reproducibility of this issue, there’s no way to tell if it’s fixed until it happens again. So I’m looking for feedback on whether this code could lead to the symptoms I’m seeing, or if I need to start coming up with other theories.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-18T06:02:44+00:00Added an answer on May 18, 2026 at 6:02 am

    Well, you are explicitly violating the contract for GlobalAlloc(). Your hope that Marshal.PtrToStructure() will call GlobalLock is unfounded, it has no way to tell whether the passed IntPtr is a handle or a pointer.

    GlobalAlloc is a fairly hopelessly outdated legacy function from the Windows 3.x era. Yes, it is quite likely to return the address as the handle value with GlobalLock() being a no-op. But it is certainly not documented to do this. CoTaskMemAlloc() is the better mouse trap.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Short version: How can I map two columns from table A and B if
Short version: Can we read from dozens or hundreds of table partitions in a
Possible Duplicate: Getting a value from HttpServletRequest.getRemoteUser() in Tomcat without modifying application Short version:
Short version: How do I write this query in squeel? SELECT OneTable.*, my_count FROM
Short version: I want to trigger the Form_Load() event without making the form visible.
Short version: I'm wondering if it's possible, and how best, to utilise CPU specific
Short version: assuming I don't want to keep the data for long, how do
Short Version: When I've created a Channel using ChannelFactory on a client which uses
Short version : echo testing | vim - | grep good This doesn't work
Short version: I have a similar setup to StackOverflow. Users get Achievements. I have

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.