% (Tracking Reference)

A tracking reference is similar to a C++ reference, to specify that a variable is passed to a function by reference and to create an alternative name for an object. However, the object referenced by a tracking reference can be moved during execution by the common language runtime garbage collector. For more information on C++ references, see References (C++).


A tracking reference is updated by the garbage-collected heap in much the same way that a handle to a reference is updated, when the object moves on the garbage-collected heap.

Use a tracking reference to bind to an object that could possibly be on the garbage-collected heap. Use a tracking reference to a handle when binding to an object of a CLR type on the garbage-collected heap.

It is not possible to have a native C++ reference to an object on the garbage-collected heap.

A tracking reference can point to a whole object, data member, or storage location.

A tracking reference can only be declared on the stack. A tracking reference cannot be a member of a class.

Tracking references are valid to value types and handles.

You can have references to native types and native pointers.

When a tracking reference is initialized, it performs the equivalent of a shallow copy, a "pointer" to shared memory, which is the same behavior as when you initialize a native reference. Also like a native reference, when you assign to a tracking reference, a deep copy is performed, meaning that the memory location of the value is changed.

A tracking reference cannot be assigned null. A tracking reference may be reassigned to another valid object as many times as needed.

For more information about tracking references, see:


// tracking_reference_1.cpp
// compile with: /clr
ref class MyClass {
   int i;

value struct MyStruct {
   int k;

int main() {
   MyClass ^ x = gcnew MyClass;
   MyClass ^% y = x;   // tracking reference handle to reference object 

   int %ti = x->i;   // tracking reference to member of reference type

   int j = 0;
   int %tj = j;   // tracking reference to object on the stack

   int * pi = new int[2];
   int % ti2 = pi[0];   // tracking reference to object on native heap

   int *% tpi = pi;   // tracking reference to native pointer

   MyStruct ^ x2 = gcnew MyStruct;
   MyStruct ^% y2 = x2;   // tracking reference to value object

   MyStruct z;
   int %tk = z.k;   // tracking reference to member of value type

   delete[] pi;

The following sample shows how to bind a tracking reference to an array.

// tracking_reference_2.cpp
// compile with: /clr
using namespace System;

int main() {
   array<int> ^ a = gcnew array< Int32 >(5);
   a[0] = 21;
   array<int> ^% arr = a;
   arr[0] = 222;

21 222


Compiler option: /clr

See Also


Language Features for Targeting the CLR