tags:

views:

87

answers:

3

I'm writing some native C++ code which needs to be called from C# (and I can't replace the C++ native code with C# code).

I found memory corruptions while allocating/deallocating some memory in the native C++ code using malloc/free. Then I used LocalAlloc/LocalFree and HeapAlloc/HeapFree and had the same problems.

The allocations/deallocations seem to be correct, and they happen in a separate thread, created by the native code.

I was wondering which is the best allocation strategy to use in a native C++ library called by C#

EDIT: found the problem: the problem wasn't in the allocation/deallocation code, but in some memory being written after being deallocated.

A: 

The windows driver developpement kit recommend against the use of C++ for drivers.

Also the best strategy is to have the driver manage its own memory. When the c# needs to see the data then pass it a marshalled buffer and have the driver to fill it

Eric
The question is NOT about the driver, it's about a C++ library which interfaces with a driver (which is the only reason I wrote a native C++ library instead of writing C# code). Additionally the driver is a user mode USB driver, where the use of C++ is in the DDK examples.
Enrico Detoma
+1  A: 

As long as the C# side of the code uses the compiler's /unsafe switch and the fixed keyword used for holding the buffer of data, I think you should be ok.

As to the question of your memory allocation, it may not be the C++ memory allocation code that is causing the problem, it could be the way how the C++ code is interacting with the driver...maybe using VirtualAlloc/VirtualFree pair as per the MSDN docs...

Edit: When you try to allocate the buffer to hold the data from the C++ side after interacting with the driver...possibly a race-condition or interrupt latency is causing a memory corruption...just a thought...

Hope this helps, Best regards, Tom.

tommieb75
No, the driver doesn't allocate memory. I will edit the question because the problem has nothing to do with the driver itself.
Enrico Detoma
@Enrico: ahh...sorry... I will edit my answer accordingly....
tommieb75
@Enrico: I have edited my answer...I hope it does shed some light on this...
tommieb75
I'll investigate the interaction between C++ and the driver, because I've run out of ideas about the memory allocation code
Enrico Detoma
Found the problem: it was a problem of memory being written from a ReadFile from the driver AFTER being deallocated. Thank you for making me think of another problem than the allocation/deallocation routines
Enrico Detoma
@Enrico: Great to hear you found the problem! :)
tommieb75
+1  A: 

Your question is missing essential details, it isn't at all clear whether the memory allocated by the C++ code needs to be released on the C# side. That's normally done automatically with, say, the P/Invoke marshaller or the COM interop layer in the CLR. Or can be done manually by declaring a method argument as IntPtr, then use of the Marshal class.

If it is done automatically you must use the COM memory allocator, CoTaskMemAlloc(). If you marshal yourself you could also use GlobalAlloc(), release on the C# side with Marshal.FreeHGlobal(). There isn't any advantage to using GlobalAlloc(), you might as well use CoTaskMemAlloc() and release with Marshal.FreeCoTaskMem().

But you should have noticed this yourself. Allocating with malloc() or HeapAlloc() on the C++ side causes leaks instead of corruption if the managed code releases the memory. Vista and Win7 have a much stricter heap manager, it terminates the program if it notices a bad release.

It sounds to me that you have simple heap corruption in your C++ code. That is the most common scourge of unmanaged C++ programming, over-running the end of a buffer, writing to memory that's been freed, bad pointer values. The way to get rid of bugs like these is a careful code review and use of a debug allocator, such as the one provided by <crtdbg.h>. Good luck with it.

Hans Passant
Right: actually it was heap corruption due to memory written after being deallocated.
Enrico Detoma