Those 4 lines create a managed array of integers (System::Int32 value type). I prefer the syntax of the first version but I would understand people using the 4th:
Int32 mai = new Int32 ;
Int32 mai_1 __gc  = new Int32 ;
Int32 mai_2 = __gc new Int32 ;
int mai_3 __gc  = new int __gc  ;
The 4th does require the __gc on each side. They are compiled to the same IL:
IL_0044: newarr [mscorlib]System.Int32
IL_0049: stloc.s V_5
IL_004b: ldloc.s V_5
IL_004d: call instance void [mscorlib]System.Array::Initialize()
IL_0052: ldloc.s V_5
IL_0054: stloc.s mai
The following line creates a native array of integers:
int * nativeArrayOfInt = new int ;
delete nativeArrayOfInt ;
Of course, it produces quite different IL:
IL_0074: call void * modopt( [mscorlib] System.Runtime.CompilerServices.CallConvCdecl ) 'new' ( unsigned int32 )
IL_0079: stloc.s nativeArrayOfInt
You cannot create a managed array of System::Void structures even by inserting __gc all over the places 😉
System::Void arrayOfVoidManagedPointer __gc  = __gc new System::Void __gc  ; // Error
By the way, the Void Structure documentation says "This structure has no members, and you cannot create an instance of this structure.” .
Well, it does have a Void Members link. I reported the bug even if I might be missing the point.
For all practical purpose, "System::Object *" is the managed version of the native "void *"
À bientôt / Hasta el rato / 'til next time.