What are the differences between creating an instance of a .NET object in C++ that is managed vs. unmanaged. That is to say, what are the differences between these to statements:
StreamWriter ^stream = gcnew StreamWriter(fileName);
versus
StreamWriter *stream = new StreamWriter(fileName);
My assumption is that if I use gcnew, the memory allocated for StreamWriter will be managed by the garbage collector. Alternatively if I use the pointer(*) and new keyword, I will have to call delete to deallocate the memory.
My real question is: will the garbage collector manage the memory that is being allocated inside of the .NET objects? For instance if a .NET object instantiates another object, and it goes out of scope - will the garbage collector manage that memory even if I use the pointer(*) and new keyword and NOT the gcnew and handle(^).
Code that executes under the control of the runtime is called managed code. Conversely, code that runs outside the runtime is called unmanaged code. COM components, ActiveX interfaces, and Windows API functions are examples of unmanaged code.
Similar to this, C# is one language that allows you to use unmanaged constructs such as pointers directly in code by utilizing what is known as unsafe context which designates a piece of code for which the execution is not managed by the CLR.
When not specified, C++ is unmanaged C++, compiled to machine code. In unmanaged C++ you must manage memory allocation manually. Managed C++ is a language invented by Microsoft, that compiles to bytecode run by the . NET Framework.
The application is written in the languages like Java, C#, VB.Net, etc. are always aimed at runtime environment services to manage the execution and the code written in these types of languages are known as managed code.
In C++/CLI, you can't new
a .NET object, you'll get something similar to the following error:
error C2750: 'System::Object' : cannot use 'new' on the reference type; use 'gcnew' instead
Usage of new
for .NET objects is allowed in the older Managed Extensions for C++ (/clr:oldsyntax
compiler flag). "Managed C++" is now deprecated because it is horrible. It has been superceded by C++/CLI, which introduced the ^
and gcnew
.
In C++/CLI, you must use gcnew
(and ^
handles) for managed types and you must use new
(and *
pointers) for native types. If you do create objects on the native heap using new
, it is your responsibility to destroy them when you are done with them.
Ideally you should use a smart pointer (like std::shared_ptr
or std::unique_ptr
) to manage the object on the native heap. However, since you can't have a native smart pointer as a field of a ref class, this isn't entirely straightforward. The simplest and most generic approach would probably be to write your own smart pointer wrapper ref class that correctly implements IDisposable
.
When you create an object with gcnew it is binded to the garbage collector, and the garbage collector will be responsible for destroying it.
If you use new it won't be binded to the garbage collector, and it will be your responsibility to delete the object.
Just to clarify:
If you have a managed C# object that contains within it an unmanaged object, the garbage collector will not delete the unmanaged object. It will just call the managed object's destructor (if it exists) before it is deleted. You should write your own code in the destructor to delete the unmanaged objects you created.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With