Introduction

Managed C++ allows you to declare and use Managed .NET arrays which means you
don't have to do memory allocation of your own and garbage collection will take
care of memory de-allocation. Managed .NET arrays are basically objects of the
System::Array class and thus you have the additional benefit that you can call
methods of the System::Array class on your Managed .NET arrays. Both single and
multi-dimensional arrays are supported though the syntax is slightly different
from that used with old-style unmanaged arrays.

Single dimensional arrays

Arrays of a Reference type

Here the syntax is not much too different from that in unmanaged code, except
that the array we create will be managed and thus garbage collected. Just as in
unmanaged arrays, the array index is zero based.

Arrays of a Value type

For value types you have to explicitly use the __gc keyword when declaring
arrays. If we do not use the __gc keyword the new
operator will create an unmanaged array. But of course, the array members are
still native value types and thus we need to box them into managed types using
the __box keyword when passing them to Console::Write.

Whoa! What's that, eh? Looks really weird, huh? I thought so too when I first
came across the Managed C++ style of declaring Managed .NET arrays. You now have
just one pair of brackets and each of the dimensional indexes are separated by
commas. Unlike in unmanaged arrays, a 2-dimensional array is NOT an array of
arrays. It is simply a 2-dimensional array.

Jagged arrays

Jagged arrays are multi-dimensional arrays that are non-rectangular. For
example, you can have a 2-dimensional array where each of the single
dimensional sub-arrays are of a different dimension. Unfortunately you cannot
have jagged arrays in Managed C++ because there is currently no
support for jagged arrays. What might piss you off even more is the fact that C# supports jagged arrays. But then you can always simulate jagged
arrays which is what I did. It's not the same thing really, and I do hope they
add jagged array support in the next release of VC++ .NET.

What I did was to create an array of System::Array objects and
then I initialized each of those System::Array objects to an array
of String objects. And we access an object as Multi[i]->GetValue(j)
where i and j are the dimensional indexes. I know that
some of you are groaning right now, but I couldn't find any alternative
solution. I have posted this in the VC++ .NET newsgroups too but haven't got any
responses.

Arrays as Function arguments

Array of Managed types

Well that was rather straightforward, wasn't it? I have used
GetUpperBound which is a member method of the System::Array
class on our array. As mentioned earlier and as I will explain later down below,
we can use any System::Array method on our arrays.

Array of value types

Well this is just about similar to the previous version except that we have
used the __gc keyword here. One very interesting issue here is
that arrays of value types are passed by reference. This might seem odd at
first glance, but remember that the array itself is a System::Array
object and is thus a managed type which means it's always passed by reference.

LOL. I can imagine the incredulous look on some of your faces. For whatever
reasons they might have had, Microsoft have decided to make it this way and so
be it. After all this is C++ and it's not ever expected to make
things easier for anyone. Well, so whenever we want to return a managed array,
we suffix our function name with our array's dimensional order. Well, when you
consider that in unmanaged C++ there was no way to actually return an array
except by returning a pointer to it's first element, I must say that this is a
great improvement. Now you can actually do something like this.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

Nish is a real nice guy who has been writing code since 1990 when he first got his hands on an 8088 with 640 KB RAM. Originally from sunny Trivandrum in India, he has been living in various places over the past few years and often thinks it’s time he settled down somewhere.

Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com.

Comments and Discussions

I'm stuck with some really strange array behavior. I've put together a managed array of TextBoxs for a simple GUI application. The form class has the textBox array declared as a private variable. My declaration and instantiation work fine in the constructor and I can pass the array as an argument to functions as Nish described in his article. However, passing the array as an argument is the only way I can get another class function to access it; if I try to use the class variable it throws Null Pointer.

I was stuck here for 4 hours and 30 seconds after I posted figured out what was going on. I was actually redeclaring another boardText array within the scope of the constructor. Once I got rid of the array<> in front of the boardText in the constructor everything works as it should.

suppose I want to use unmanaged arrays in unmanaged C++ code, but need to pass this new array to C# or managed code. Is there a way to do this without simply having to copy the array element by element?