The code you wrote never worked.
HeapSize returns the size of the heap, for example, something allocated by calling HeapAlloc . The pointer provided by HeapSize must be the pointer returned by the HeapAlloc call:
lpMem [in]
Pointer to a memory block the size of which the function will receive. This is the pointer returned by the HeapAlloc or HeapReAlloc function.
You call HeapSize , but provide a pointer that can be anywhere inside this heap; or not in this heap at all:
PtrStart = (byte*)Marshal.StringToHGlobalAnsi(sb.ToString()); Size = UnManagedMemory.SizeOf(PtrStart); PtrWriteNextValue = PtrStart + Size - 1; PtrReturnNextValue = PtrStart;
Not only Marshal.StringToHGlobalAnsi() returns a pointer somewhere on the heap, not a pointer to the heap, you donโt even know which heap the pointer is allocated from, because several heaps can be allocated in the process.
None of this matters because you seem to have a fundamental misunderstanding of the purpose of this function - you seem to be using it to get the size of the allocation made inside the heap. The memory returned by Marshal.StringToHGlobalAnsi() is not allocated by calling HeapAlloc() (because it is not a heap!), It is allocated by calling AllocHGlobal . The allocated memory must be freed by calling Marshal.FreeHGlobal() :
From the Marshal.StringToHGlobal() documentation:
Since this method allocates the unmanaged memory needed for the string, always free the memory by calling FreeHGlobal.
This Marshal method has nothing to do with HeapAlloc , HeapSize or related functions.
If you really want to know the size of the memory allocation of the pointer returned by Marshal.StringToHGlobal() , you can dig through the source of the Marshal class and find out that it uses the win32 LocalAlloc function. It so happened that LocalAlloc has a sister function, LocalSize , which can actually be used to determine the size of the selection.
However, there is no guarantee that this will work in the future, as the .Net infrastructure does not guarantee that it will continue to use LocalAlloc . If they change the internal elements of LocalSize , it may stop working.
...
All said:
I donโt think that this is what you wanted to do first
Looking at your code again:
PtrStart = (byte*)Marshal.StringToHGlobalAnsi(sb.ToString()); Size = UnManagedMemory.SizeOf(PtrStart); PtrWriteNextValue = PtrStart + Size - 1; PtrReturnNextValue = PtrStart;
You are trying to find the length of the ansi string returned to you.
All this work of HeapSize or LocalSize completely irrelevant.
If you just want to find the length of the string "ansi", you just need to implement a silly simple string length or use any of the existing implementations there.
The following program uses Marshal.StringToHGlobal() and prints:
String: 'Hello'; Length: 5
public static void Main( string[] args ) { IntPtr strPtr = IntPtr.Zero; string str = "Hello"; try { strPtr = Marshal.StringToHGlobalAnsi( str ); Console.Out.WriteLine( "String: '{0}'; Length: {1}", str, AnsiStrLen( strPtr ) ); } finally { if( strPtr != IntPtr.Zero ) { Marshal.FreeHGlobal( strPtr ); } } } public static int AnsiStrLen( IntPtr strPtr ) { int size = 0; while( Marshal.ReadByte( strPtr ) != 0 ) { size++; strPtr = IntPtr.Add( strPtr, 1 ); } return size; }