Memory management problem

G

Guest

I have this structure that I am using in conjunction with
NetLocalGroupAddMembers:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct LOCALGROUP_MEMBERS_INFO_3
{
[MarshalAs(UnmanagedType.LPWStr)] public string lgrmi3_domainandname;
}

I am having failures that stinky hugely of either memory allocation being
incorrectly sized, or simply using the wrong allocation method. To test
this, I snipped the code somewhat and threw it into nUnit. This is what I
have:

/// <summary>
/// Hammers memory allocation to try to force a failure
/// </summary>
[Test]
public void TestMemoryAllocation()
{
System.Console.Write("\n\n");
System.Console.Write("Testing memory issue...\n");
for (int i=1; i<=15; i++)
{
System.Console.Write("Count: "+ i.ToString());
CatchAndRelease();
System.Console.Write(".\n");
}
}

/// <summary>
/// Allocates and clears memory
/// </summary>
public void CatchAndRelease()
{
try
{
LOCALGROUP_MEMBERS_INFO_3 MemberToAdd;
LOCALGROUP_MEMBERS_INFO_3[] MembersToAdd;
IntPtr bufPtr=IntPtr.Zero;

// Initialize Variables
MemberToAdd.lgrmi3_domainandname = "DOMAIN\\USERNAME";
MembersToAdd = new LOCALGROUP_MEMBERS_INFO_3[1] { MemberToAdd };

// Allocate memory and convert data into pointer
bufPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LOCALGROUP_MEMBERS_INFO_3)) *
MembersToAdd.Length);
Marshal.StructureToPtr(MembersToAdd[0], bufPtr, true);

// Free memory and zero out the pointer
Marshal.FreeHGlobal(bufPtr);
bufPtr = IntPtr.Zero;
}

catch (Exception e)
{
System.Windows.Forms.MessageBox.Show("Exception thrown " + e.Message );

}
}
}

Seems to work okay with a repeat count of < 3. It either explodes or throws
an OutofMemoryException when I repeat the fucntion 3 or more times.

If someone could educate me on whatever i'm doing wrong here, I would muchly
appreciate!

Thanks,
Brandon
 
M

Martin Dechev

Hi,

I tested your code and the bottleneck seems to be the call to
Marshal.StructureToPtr. It seems to throw this exception when the pointer
points to an empty allocated buffer and you call it with fDeleteOld=true. I
can't explain where this exception comes from. I suppose they loop through
the managed references to see if there is a reference pointing to this
address and the exception is thrown in this loop. Maybe someone (MSFT) could
shed some light.

As it is stated in the remarks section in
http://msdn.microsoft.com/library/e...opServicesMarshalClassStructureToPtrTopic.asp
If not otherwise specified (read: if fDeleteOld=false) the function
allocates a new block of memory, fills it with the data in the passed
structure and hooks it up to the pointer. So here's the best I could come up
with:

// Allocate memory and convert data into pointer
// Here we just create a valid pointer:
IntPtr bufPtr = Marshal.AllocHGlobal(0);
// Call StructureToPtr with fDeleteOld=false
Marshal.StructureToPtr(MembersToAdd[0], bufPtr, false);

Hope this helps
Martin Dechev
ASP.NET MVP
Brandon Langley said:
I have this structure that I am using in conjunction with
NetLocalGroupAddMembers:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct LOCALGROUP_MEMBERS_INFO_3
{
[MarshalAs(UnmanagedType.LPWStr)] public string lgrmi3_domainandname;
}

I am having failures that stinky hugely of either memory allocation being
incorrectly sized, or simply using the wrong allocation method. To test
this, I snipped the code somewhat and threw it into nUnit. This is what I
have:

/// <summary>
/// Hammers memory allocation to try to force a failure
/// </summary>
[Test]
public void TestMemoryAllocation()
{
System.Console.Write("\n\n");
System.Console.Write("Testing memory issue...\n");
for (int i=1; i<=15; i++)
{
System.Console.Write("Count: "+ i.ToString());
CatchAndRelease();
System.Console.Write(".\n");
}
}

/// <summary>
/// Allocates and clears memory
/// </summary>
public void CatchAndRelease()
{
try
{
LOCALGROUP_MEMBERS_INFO_3 MemberToAdd;
LOCALGROUP_MEMBERS_INFO_3[] MembersToAdd;
IntPtr bufPtr=IntPtr.Zero;

// Initialize Variables
MemberToAdd.lgrmi3_domainandname = "DOMAIN\\USERNAME";
MembersToAdd = new LOCALGROUP_MEMBERS_INFO_3[1] { MemberToAdd };

// Allocate memory and convert data into pointer
bufPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LOCALGROUP_MEMBERS_INFO_3)) *
MembersToAdd.Length);
Marshal.StructureToPtr(MembersToAdd[0], bufPtr, true);

// Free memory and zero out the pointer
Marshal.FreeHGlobal(bufPtr);
bufPtr = IntPtr.Zero;
}

catch (Exception e)
{
System.Windows.Forms.MessageBox.Show("Exception thrown " + e.Message );

}
}
}

Seems to work okay with a repeat count of < 3. It either explodes or throws
an OutofMemoryException when I repeat the fucntion 3 or more times.

If someone could educate me on whatever i'm doing wrong here, I would muchly
appreciate!

Thanks,
Brandon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top