Rakeshsahu
asked on
Free unmanaged memory from C#
How do I free memory allocated on unmanaged heap from a C# App?
Below is the sample code which one can use.
There is a C# app calling a native c-style DLL's method which is allocating some memory.
-------------------------- ---------- ----
// MemoryDll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "MemoryDll.h"
#include <stdlib.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is an example of an exported variable
MEMORYDLL_API int nMemoryDll=0;
// This is an example of an exported function.
MEMORYDLL_API int AllocateMemory(char ** achMemory)
{
*achMemory=(char*)calloc(1 0*1000*100 0,1);
return 0;
}
MEMORYDLL_API int FreeMemory(char ** achMemory)
{
free((char*)*achMemory);
return 0;
}
// This is the constructor of a class that has been exported.
// see MemoryDll.h for the class definition
CMemoryDll::CMemoryDll()
{
return;
}
-------------------------- ---------- ---------- ----
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServ ices;
namespace JeffSuggestion
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private static string strInBuff = "";
// [DllImport("CryptoUtils.dl l")]
// static extern int EncryptBufferUsingSymmetri cKey(out IntPtr outBuffer, out Int32 outBufferLen, IntPtr inBuffer, Int32 inBufferLen, IntPtr SymmKey, Int32 symmKeyLen);
[DllImport("MemoryDll_debu g.dll")]
static extern int AllocateMemory(out IntPtr outBuffer);
[DllImport("MemoryDll_debu g.dll")]
static extern int FreeMemory(IntPtr outBuffer);
private System.Windows.Forms.Butto n button1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Cont ainer components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Butto n();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(140, 92);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "unsafe";
this.button1.Click += new System.EventHandler(this.b utton1_Cli ck);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.but ton1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.F orm1_Load) ;
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
}
// [DllImport("CryptoUtils.dl l")]
// static extern void Funx(out IntPtr outBuffer, out Int32 outBufferLen, IntPtr inBuffer, Int32 inBufferLen);
private void button1_Click(object sender, System.EventArgs e)
{
string strInBuff1 = "1234567890123456789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 6789012345 67890";
for(int j=0; j < 10; j++)
strInBuff += strInBuff1;
for(int i=0; i < 10; i++)
x();
MessageBox.Show("DONE");
}
unsafe private void x()
{
Int32 outBufferLen;
IntPtr outBuffer;
int iRet = -1;
Byte[] inBuffer = null;//{ 1, 2, 3, 4 };
// Byte[] inSymm = null;
inBuffer = System.Text.Encoding.UTF8. GetBytes(s trInBuff);
// inSymm = Convert.FromBase64String(" vbWMjXdNLL 6rQbXzvKKT rg==");
fixed (Byte* p = (Byte *) &inBuffer[0])
{
iRet = AllocateMemory(out outBuffer);
}
FreeMemory(outBuffer);
// fixed (Byte* p1 = (Byte *) &inSymm[0])
// {
// fixed (Byte* p = (Byte *) &inBuffer[0])
// {
// iRet = EncryptBufferUsingSymmetri cKey(out outBuffer, out outBufferLen, (IntPtr) p, inBuffer.Length,(IntPtr) p1, inSymm.Length );
// }
// }
// Byte *q = (Byte *) outBuffer;
// Access q[0], etc...
}
}
}
-------------------------- ---------- ----
Below is the sample code which one can use.
There is a C# app calling a native c-style DLL's method which is allocating some memory.
--------------------------
// MemoryDll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "MemoryDll.h"
#include <stdlib.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is an example of an exported variable
MEMORYDLL_API int nMemoryDll=0;
// This is an example of an exported function.
MEMORYDLL_API int AllocateMemory(char ** achMemory)
{
*achMemory=(char*)calloc(1
return 0;
}
MEMORYDLL_API int FreeMemory(char ** achMemory)
{
free((char*)*achMemory);
return 0;
}
// This is the constructor of a class that has been exported.
// see MemoryDll.h for the class definition
CMemoryDll::CMemoryDll()
{
return;
}
--------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServ
namespace JeffSuggestion
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private static string strInBuff = "";
// [DllImport("CryptoUtils.dl
// static extern int EncryptBufferUsingSymmetri
[DllImport("MemoryDll_debu
static extern int AllocateMemory(out IntPtr outBuffer);
[DllImport("MemoryDll_debu
static extern int FreeMemory(IntPtr outBuffer);
private System.Windows.Forms.Butto
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Cont
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Butto
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(140, 92);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "unsafe";
this.button1.Click += new System.EventHandler(this.b
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.but
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.F
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
}
// [DllImport("CryptoUtils.dl
// static extern void Funx(out IntPtr outBuffer, out Int32 outBufferLen, IntPtr inBuffer, Int32 inBufferLen);
private void button1_Click(object sender, System.EventArgs e)
{
string strInBuff1 = "1234567890123456789012345
for(int j=0; j < 10; j++)
strInBuff += strInBuff1;
for(int i=0; i < 10; i++)
x();
MessageBox.Show("DONE");
}
unsafe private void x()
{
Int32 outBufferLen;
IntPtr outBuffer;
int iRet = -1;
Byte[] inBuffer = null;//{ 1, 2, 3, 4 };
// Byte[] inSymm = null;
inBuffer = System.Text.Encoding.UTF8.
// inSymm = Convert.FromBase64String("
fixed (Byte* p = (Byte *) &inBuffer[0])
{
iRet = AllocateMemory(out outBuffer);
}
FreeMemory(outBuffer);
// fixed (Byte* p1 = (Byte *) &inSymm[0])
// {
// fixed (Byte* p = (Byte *) &inBuffer[0])
// {
// iRet = EncryptBufferUsingSymmetri
// }
// }
// Byte *q = (Byte *) outBuffer;
// Access q[0], etc...
}
}
}
--------------------------
You already call FreeMemory function. Do you have some problem with it?
ASKER
Yes.
If one compiles and runs it then calling FreeMemory has no effect.
If the same DLL is used from unmanaged code then FreeMemory works but not from C#.
If one compiles and runs it then calling FreeMemory has no effect.
If the same DLL is used from unmanaged code then FreeMemory works but not from C#.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.