Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Friday, February 8, 2008 7:24 AM
I understand that the new operator allocates on the CRT heap, and gcnew allocates on the managed heap. I also understand that if I declare an instance of a managed class like so:
ManagedClass newInstance;
Then newInstance is automatically allocated on the managed heap.
What I am not sure about is if I write code like this:
ManagedClass* newInstancePtr = new ManagedClass();
Where is the object that newInstancePtr points to allocated? This code compiles and appears to execute with no problems.
Based on the documentation, the managed object is being allocated on the CRT heap. Is this really what is happening, and more importantly, is this a safe thing to do?
Thanks,
Ian
All replies (6)
Friday, February 8, 2008 12:39 PM âś…Answered
No, it's not.
Here's escription I know of.
Managed class declaration, according to ECMA C++/CLI standard, must begin with "ref", representing "reference type", meaning the object is a reference in managed heap to an object.
ref class MyClass;
Managed objects can only be instantiated on the managed heap, regardless of automatic declarations. For above MyClass:
void foo()
{
MyClass mc; // still allocated on the managed heap, just implicit
}
Handles must be declared with ^ (hat). Handle is somewhat a pointer to an object in managed heap. You can get a handle to an object by either using address of operator, or, by using gcnew.
void foo()
{
MyClass ^hmyclass = gcnew MyClass;
}
It was planned to allow instantiation of unmanaged objects to be instantiated on the managed heap as well, but it's not implemented yet. So, you can rely the fact that;
if you see
MyObject*
That's a pointer to an object in unmanaged heap.
if you see
MyObject^
That's a handle to a reference type on managed heap.
If you see operator 'new', that's unmanaged object dydnamic instantiation
If you see operator 'gcnew', that's managed object instantiation.
Therefore EScriptProcedure* is unmanaged. Also, "new EScriptProcedure" is unmanaged.
Friday, February 8, 2008 10:08 AM
This code is not compiled in VC++ 2005 and later. Maybe in VC++ 2003, where new was used both for managed and unmanaged objects.
Friday, February 8, 2008 11:23 AM
Maybe my confusion then is what constitutes a managed class, because I can assure you that the code is being compiled in VS 2005.
The project setting for CLR support is set to "No Common Language Runtime support", but some classes, including the one I am creating, have the cpp file set to "Common Language Runtime Support (/clr)". The class declaration is, in this case:
class EScriptProcedure
{
// member declarations..
}
The class which contains the code "EScriptProcedure* procedurePtr = new EScriptProcedure()", is not compiled with /clr.
So my question becomes: Is EScriptProcedure a managed class?
Thanks,
Ian
Friday, February 8, 2008 1:41 PM
Just to be sure I'm clear about this. Compiling a .cpp file with the /clr switch means that the class in that file can reference managed types, but is not itself a managed type unless declared as one with the ref keyword.
Thank you for your help.
Ian
Friday, February 8, 2008 3:31 PM
Yes, that's correct. /clr implies "support" for, not "only", CLR.
Wednesday, April 9, 2008 11:04 AM
The new
and gcnew
operator are similar. Both allocate memory and invoke the constructor of the object. Whereas new
allocates memory from a native heap and returns a pointer, gcnew
will allocate memory from the GC heap and return a handle. A boxed value type is easy to recognize, as the type is simply a handle to value type. For example:
int m = 42; // integer on the stack
int* n = new int(42); // integer on a native heap
int^ o = gcnew int(42); // boxed integer on the GC heap
There are other ways to create boxed value types, but I will leave that for another time when I discuss the implementation of boxed value types.
Why is it important to distinguish whether an instance of an object is on the GC heap or a native heap? The GC algorithm implemented by the CLR is a generational compacting garbage collector. This means that the memory location of the object can change upon each garbage collection. This does not happen on the native heap. A pointer refers to an instance in memory that never moves. The garbage collector ensures that a handle always points to the right instance.