none
Memory Leak when converting array of object to Intptr RRS feed

  • Question

  • The purpose is to convert an array of object to Intptr to be able to send it to a native code.  the We get the memory leak especially when the array is filled with strings.

    Below is my source code.

    [ComConversionLoss]
            public struct ONEVENTSTRUCT
            {
                public int number;
                [ComConversionLoss]
                public IntPtr pEventAttributes;
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                try
                {
                    count = 500;
    
                    //Object Number
                    numAttribut = 12;
    
                    obj = new object[count];
                    object str = new object();
    
                    for (int i = 0; i < numAttribut; i++)
                    {
                        str = "String for test " + i.ToString();
                        obj[i] = str;
                    }
    
                    ONEVENTSTRUCT[] objTemp = new ONEVENTSTRUCT[count];
    
                    //Allocate
                    for (int i = 0; i < count; i++)
                    {
                        objTemp[i].number = i;
                        FromObjectToIntPtr(ref objTemp[i].pEventAttributes, obj);
                    }
    
                    //Free memory
                    for (int i = 0; i < count; i++)
                    {
                        for (int j = 0; j < numAttribut; j++)
                        {
                            VariantClear(objTemp[i].pEventAttributes);
                            objTemp[i].pEventAttributes = (IntPtr)(objTemp[i].pEventAttributes.ToInt32() + variant_size);
                        }
    
                        Marshal.DestroyStructure(objTemp[i].pEventAttributes, typeof(IntPtr));
                    }
    
                }
                catch (Exception exp)
                {
                    MessageBox.Show(exp.Message);
                }
            }
    
            public void FromObjectToIntPtr(ref IntPtr IntPtrValues, object[] values)
            {
                IntPtrValues = Marshal.AllocCoTaskMem(numAttribut * variant_size);
    
                IntPtr pos = IntPtrValues;
    
                for (int ii = 0; ii < numAttribut; ii++)
                {
                    Marshal.GetNativeVariantForObject(values[ii], IntPtrValues);
    
                    IntPtrValues = (IntPtr)(IntPtrValues.ToInt32() + variant_size);
                }
    
                IntPtrValues = pos;
    
                pos = IntPtr.Zero;
            }

    Any idea?

    Thanks in advance.

    Wednesday, February 20, 2013 8:22 AM

Answers

  • I think the answer is very simple.  YOu need to understand what the Allocate function actually does in th eline below

       IntPtrValues = Marshal.AllocCoTaskMem(numAttribut * variant_size);

    The allocate function returns a pointer to an object the contains the memory you requested.  You must delalocate the object by using the returned pointer from the allocate function.  You never call a deallocate function, instead you just set the variable "pos" to zero.  You really want to set the object that pos points to.  Try reallocating the object to size 0.

    Marshal.ReAllocCoTaskMem(pos,0);

    pos = IntPtr.Zero;


    jdweng

    Thursday, February 21, 2013 10:44 PM

All replies

  • Since you call Marshal.AllocCoTaskMem, maybe you should latter call Marshal.FreeCoTaskMem.

    Wednesday, February 20, 2013 11:33 AM
  • Hi ABA Memory,

    From your description, I ‘d like to move this post to  the most related forum.

    There are more  experts in this aspect, so you will get  better support and  may have more luck getting answers.

    Thanks for your understanding.

    Regards,


    Lisa Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, February 21, 2013 8:52 AM
  • Hi There,

    What is the method "

    VariantClear

    "

    And the value of "variant_size"?

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, February 21, 2013 8:42 PM
    Moderator
  • I think the answer is very simple.  YOu need to understand what the Allocate function actually does in th eline below

       IntPtrValues = Marshal.AllocCoTaskMem(numAttribut * variant_size);

    The allocate function returns a pointer to an object the contains the memory you requested.  You must delalocate the object by using the returned pointer from the allocate function.  You never call a deallocate function, instead you just set the variable "pos" to zero.  You really want to set the object that pos points to.  Try reallocating the object to size 0.

    Marshal.ReAllocCoTaskMem(pos,0);

    pos = IntPtr.Zero;


    jdweng

    Thursday, February 21, 2013 10:44 PM