Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.OutOfMemoryException when getting string array from c++ on c#

My C++ function

    void FillArray(wchar_t** arr)
    {
         // some code
         for(i= 0;i<end;++i)
         {
             wcsncpy(arr[i],InforArray[i],MaxLength);
             count++;
         } 
     }

My C# signature is

[DllImport("Native.dll", CharSet = CharSet.Unicode,EntryPoint = "FillArray")]
        internal static extern void FillArray(
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr)] 
            IntPtr[] OutBuff);

And the C# code itself:

int maxLen = 256;


int count = GetPropertyCount(ref eData);
IntPtr[] buffer = new IntPtr[count];
for (int i = 0; i < count; i++)
     buffer[i] = Marshal.AllocHGlobal(maxLen);

FillArray(buffer);

string[] output = new string[count];

for (int i = 0; i < count; i++)
{
      output[i] = Marshal.PtrToStringUni(buffer[i]); 
      Marshal.FreeHGlobal(buffer[i]);
}

The data is populated with no problems in c++ loop, but when exiting FillArray I got "An unhandled exception of type 'System.OutOfMemoryException' occurred"

Any ideas why?

like image 677
Assaf Avatar asked Jul 21 '11 17:07

Assaf


1 Answers

Given the nature of the exception you are encountering the program is failing attempting to allocate memory, which is occuring in two spots in your example code Marshal.AllocHGlobal() and Marshal.PtrToStringUni(). So unless GetPropertyCount() is returning Int.MaxValue somehow, the program is likely failing because wcsncpy does not null terminate the copied string. So the call to Marshal.PtrToStringUni() is allocating all your machine's memory attempting to determine where the copied strings actually end. Try using the PtrToStringUni API that allows you to provide the number of characters to copy.

like image 114
Clayton Avatar answered Sep 28 '22 06:09

Clayton