Memory allocation / deallocation when working with C # and C ++ unmanaged

I am working with unmanaged C # and C ++ code and there are two things that I do not understand when dealing with memory. If someone can help me understand:

  • Where the variable is dynamically allocated in C # (using the new one) and then passed to unmanaged C ++ code. Should this memory variable be manually deallocated under unmanaged C ++ code by the user?

  • If a variable is dynamically allocated in C ++ unmanaged (using a new one) and then passed to C #, can we say that the garbage collector will free that memory?

+3


source to share


3 answers


It's very easy!

  • Depending on
  • Depending on

Eh, I'm sorry.



  • Under typical conditions, C # will keep track of the memory and dispose of it at any time after it is no longer used on the C # side. It doesn't have the ability to track references on the C ++ side, so one of the common mistakes in interop is that the memory is freed before the unmanaged side is executed on it (which will load the FUN). This only applies to cases where memory is referenced directly and not when copied (the typical case is byte[]

    one that is pinned throughout an unmanaged call). Do not use automatic sorting when the lifespan of an object / pointer passed to unmanaged code must be longer than the invocation of the method being called.
  • Under typical conditions, C # does not have the ability to track memory allocations in C ++ code, so you cannot rely on automatic memory management. There are exceptions (like some COM scripts), but you almost always need to manage memory manually. This usually means sending a pointer back to the C ++ code for deallocation, unless it uses a global allocator of some type (like CoMemoryInitialize). Remember, in an unmanaged world, there is no single memory manager that can be safely called to reclaim memory; you don't really have the information you need.

This only applies to pointers, of course. Passing integers is fine, and using automatic sorting usually means the marshaller does most of the niceties (although still only in the simplest case, so be careful). Unmanaged code is unmanaged - you need to be clear about how memory is allocated, and how, when, and who is responsible for cleaning up memory.

+2


source


  • No, since the object is allocated on the managed heap, the GC will handle the deal as usual. The problem is that you have to tell it not to release or change the address of the object while it is being used from unmanaged code, because the GC cannot know how long you are going to use the object from unmanaged code. This can be done using the PINNING object. See the answer to this question.

  • No, since the object is allocated in C ++ unmanaged GC heap, it won't touch it. You have to free it yourself using delete.



Edit: If you need to allocate an object in managed code and free it in unmanaged code, or vice versa, it's good to know that there is a bunch of OSes for this purpose that you can use with Marshal.AllocHGlobal and Marshal.FreeHGlobal calls from C #, in C ++ there will be similar calls.

+2


source


Generally, depending on what component

/ object

allocating memory, it is necessary to free memory. For each new

a the delete

one that did new

.

This is the ideal. If not followed for reasons like you C++

, the program may end and not exist, when the allocated memory lifecycle comes to an end, yours C#

should clear and vice versa.

+1


source







All Articles