I just saw this question and infact tried to answer it as well. But while answering I thought what could be the answer in case of C#? I am looking for some MSDN doc or any relevant source like in Java
What is the maximum dimension allowed for an array in C# like a[1][1][1][1]....[1]. I tried to search on SO but was not able to find.
The best I got up to was that "An array could theoretically have at most 2,147,483,647 elements, since it uses an int for indexing."
Also I am aware of the fact that Maximum Size that an Array can hold is
System.Int32.MaxValue
Kindly do let me know if this is a duplicate I will delete my question.
The limit is 32. I checked it with the code:
var b = Array.CreateInstance(typeof (int), new int[32]);
var a = Array.CreateInstance(typeof (int), new int[33]);
It applies for both 64 and 32-bit targeted applications.
Actually, I needn't have googled it. Straight from MSDN:
An element is a value in an Array. The length of an Array is the total number of elements it can contain. The rank of an Array is the number of dimensions in the Array. The lower bound of a dimension of an Array is the starting index of that dimension of the Array; a multidimensional Array can have different bounds for each dimension. An array can have a maximum of 32 dimensions.
About jagged arrays
However, I just noticed that the syntax you used in your edit (and also the syntax Peter used in the comments below) isn't how multi-dimensional arrays are defined in C#. Multi-dimensional arrays are defined as:
int[,,,] arr = new int[0,0,0];
And they are arrays of regular integers, that happen to have multiple dimensions. The syntax:
int[][][] = new int[0][][];
Defines something that in C# is called a jagged array. Jagged arrays are just regular, single-dimensional arrays that happen to have other arrays as elements. You can have multi-dimensional arrays of jagged arrays, or the other way around, as the MSDN article points out.
They are treated differently, however. Jagged arrays are just arrays of (effectiely) regular* objects, and as such, aren't regulated in the same way as multi-dimensional arrays. There is no theoretical limit to the number of "dimensions" a jagged array can have, and in fact the CLR happily let me run the following code:
Array arr = new int[0];
for (int i = 0; i < Int32.MaxValue - 1; i++) {
var newArr = Array.CreateInstance(arr.GetType(), 1);
newArr.SetValue(arr, 0);
arr = newArr;
}
Right up until my system became completely unresponsive and crashed. No exception was thrown.
Limiting the loop to 1000 iterations, you find that the type of the resulting array is:
System.Int32[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]...
In addition, although I can't find a source for this, the number of dimensions a jagged array can have probably isn't even limited by the single object memory limitation, because each array only has references to objects. For example, a jagged array of (eventually) Int32 with a nesting factor of, say, 1000 and 2 elements per array, would take up a negligible amount of memory (that is, on its own), but all the arrays combined would take up an exponential amount.
* With a little bit of syntax sugar. A more syntactically correct way of encoding jagged arrays would be: int[][] arr = new int[][0]; because int[] is the element type.
It's implementation defined
The number of dimensions an array can have appears to be implementation-defined. The number doesn't appear anywhere in the CLI specification, and the code provided by Peter below runs fine on Ideone's mono-2.8, where it appears the limit is 255.
Related
How can I determine size of an array (length / number of items) in C#?
If it's a one-dimensional array a,
a.Length
will give the number of elements of a.
If b is a rectangular multi-dimensional array (for example, int[,] b = new int[3, 5];)
b.Rank
will give the number of dimensions (2) and
b.GetLength(dimensionIndex)
will get the length of any given dimension (0-based indexing for the dimensions - so b.GetLength(0) is 3 and b.GetLength(1) is 5).
See System.Array documentation for more info.
As #Lucero points out in the comments, there is a concept of a "jagged array", which is really nothing more than a single-dimensional array of (typically single-dimensional) arrays.
For example, one could have the following:
int[][] c = new int[3][];
c[0] = new int[] {1, 2, 3};
c[1] = new int[] {3, 14};
c[2] = new int[] {1, 1, 2, 3, 5, 8, 13};
Note that the 3 members of c all have different lengths.
In this case, as before c.Length will indicate the number of elements of c, (3) and c[0].Length, c[1].Length, and c[2].Length will be 3, 2, and 7, respectively.
You can look at the documentation for Array to find out the answer to this question.
In this particular case you probably need Length:
int sizeOfArray = array.Length;
But since this is such a basic question and you no doubt have many more like this, rather than just telling you the answer I'd rather tell you how to find the answer yourself.
Visual Studio Intellisense
When you type the name of a variable and press the . key it shows you a list of all the methods, properties, events, etc. available on that object. When you highlight a member it gives you a brief description of what it does.
Press F1
If you find a method or property that might do what you want but you're not sure, you can move the cursor over it and press F1 to get help. Here you get a much more detailed description plus links to related information.
Search
The search terms size of array in C# gives many links that tells you the answer to your question and much more. One of the most important skills a programmer must learn is how to find information. It is often faster to find the answer yourself, especially if the same question has been asked before.
Use a tutorial
If you are just beginning to learn C# you will find it easier to follow a tutorial. I can recommend the C# tutorials on MSDN. If you want a book, I'd recommend Essential C#.
Stack Overflow
If you're not able to find the answer on your own, please feel free to post the question on Stack Overflow. But we appreciate it if you show that you have taken the effort to find the answer yourself first.
for 1 dimensional array
int[] listItems = new int[] {2,4,8};
int length = listItems.Length;
for multidimensional array
int length = listItems.Rank;
To get the size of 1 dimension
int length = listItems.GetLength(0);
yourArray.Length :)
With the Length property.
int[] foo = new int[10];
int n = foo.Length; // n == 10
For a single dimension array, you use the Length property:
int size = theArray.Length;
For multiple dimension arrays the Length property returns the total number of items in the array. You can use the GetLength method to get the size of one of the dimensions:
int size0 = theArray.GetLength(0);
In most of the general cases 'Length' and 'Count' are used.
Array:
int[] myArray = new int[size];
int noOfElements = myArray.Length;
Typed List Array:
List <int> myArray = new List<int>();
int noOfElements = myArray.Count;
it goes like this:
1D:
type[] name=new type[size] //or =new type[]{.....elements...}
2D:
type[][]name=new type[size][] //second brackets are emtpy
then as you use this array :
name[i]=new type[size_of_sec.Dim]
or You can declare something like a matrix
type[ , ] name=new type [size1,size2]
What has been missed so far is what I suddenly was irritated about:
How do I know the amount of items inside the array? Is .Length equal .Count of a List?
The answer is: the amount of items of type X which have been put into an array of type X created with new X[number] you have to carry yourself!
Eg. using a counter: int countItemsInArray = 0 and countItemsInArray++ for every assignment to your array.
(The array just created with new X[number] has all space for number items (references) of type X already allocated, you can assign to any place inside as your first assignment, for example (if number = 100 and the variable name = a) a[50] = new X();.
I don't know whether C# specifies the initial value of each place inside an array upon creation, if it doesn't or the initial value you cannot compare to (because it might be a value you yourself have put into the array), you would have to track which places inside the array you already assigned to too if you don't assign sequentially starting from 0 (in which case all places smaller than countItemsInArray would be assigned to).)
In your question size of an array (length / number of items) depending on whether / is meant to stand for "alternative" or "divide by" the latter still has to be covered (the "number of items" I just gave as "amount of items" and others gave .Length which corresponds to the value of number in my code above):
C# has a sizeof operator (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/sizeof). It's safe to use for built-in types (such as int) (and only operates on types (not variables)). Thus the size of an array b of type int in bytes would be b.Length * sizeof(int).
(Due to all space of an array already being allocated on creation, like mentioned above, and sizeof only working on types, no code like sizeof(variable)/sizeof(type) would work or yield the amount of items without tracking.)
Let's just say I'm running a physics simulation that uses integers as vertexes on a model. In this simulation I load arrays of integers to a list as the amount of vertexes may vary; like so:
List<int[]> x = new List<int[]>();
x.Add(new <int[1]>());
I know it's a bit overboard, considering to use 2GB worth of integers, but the model could range anywhere from a single object to entire open field. So, considering this process is repeated enough to take up 2GB, would each element/array have it's own 2GB as it's own object or does the entire list still count as the same object.
The list is an object, the backing array inside the list (T[], so: int[][]) is an object, and each int[] array is (separately) an object. As long as no individual array is too large, you're OK. At no point are the arrays in a List<some array> treated as contiguous, so it doesn't matter if their combined length exceeds the 2 GiB limit.
Note that you can enable very-large-object support in your configuration (<gcAllowVeryLargeObjects>) to squeeze out a slightly larger array limit - for most arrays (not bytes/single-byte elements) it changes the maximum element count to 2,146,435,071 - which is ~8 GiB in your case (int[]). That doesn't necessarily mean it is a good idea to do so :)
I have a function that can take a 1d array (double[]) as an argument while my source data is a 2d array (double[,]) of 'cnt' number of 3d points, like so
double[,] points = new double[3,cnt]
But what I actually want to do is to pass on each of the three 2nd dim arrays to the function gpu.Average(double[] arg), preferably without having to copy the content of the arrays value[i] by value[i]. Is that possible in C#?
EXAMPLE CODE
This works:
double[] points1d = new double[cnt];
// ... fill points1d with data, then
double a = gpu.Average(points1d); // <- Alea.gpu.Average() accepts a 1d array
But as said, I want to pass on the second dimension to the function gpu.Average() whithout having to run for-loops three times to copy into 1d arrays:
double[,] points2d = new double[3,cnt];
// ... fill points2d with 'cnt' items of data and
// then pass it on
double x = gpu.Average(points2d[0,??]); // How to pass on 2nd dim?
double y = gpu.Average(points2d[1,??]);
double z = gpu.Average(points2d[2,??]);
Is this possible without having to copy the data into 1d arrays?
(BTW, calculating average is not a good example use of gpu parallel library, this is just a test case comparing execution times for different data types & structures).
// Rolf
No this is not possible in managed code without copying the contents of e.g. points2d[1,*] to a new single dimensional array.
In managed code every array has to know its length, so that every index access can be checked and ArrayIndexOutOfBounds exception thrown if the index is out of bounds. The length (integer value) is stored before the first element of the array, so that the runtime knows where to find it. Now with this I guess one can see why you cannot split array into several parts and treat those as new arrays. Note that the story is even more complicated for multidimensional arrays, which have to store the number of dimensions and the size of each dimension...
What you can do is to use jagged array:
double[][] points2d = new double[3][];
points2[0] = new double[cnt];
...
gpu.Average(points2d[0]);
Jagged arrays are faster than multidimensional arrays and are recommended to be used instead of multidimensional arrays even by MS.
This question already has answers here:
Differences between a multidimensional array "[,]" and an array of arrays "[][]" in C#?
(12 answers)
Closed 9 years ago.
What is the difference between the two syntaxes?
The first one is a multi dimensional array while the second is a jagged array. You can take a look at this question to get a description of the diffrerence between the two, but here is an important snippit:
A multidimensional array creates a nice linear memory layout while a
jagged array implies several extra levels of indirection.
Looking up the value jagged[3][6] in a jagged array var jagged = new
int[10][5] works like this: Look up the element at index 3 (which is
an array) and look up the element at index 6 in that array (which is a
value). For each dimension in this case, there's an additional look up
(this is an expensive memory access pattern).
A multidimensional array is laid out linearly in memory, the actual
value is found by multiplying together the indexes. However, given the
array var mult = new int[10,30] the Length property of that
multidimensional array returns the total number of elements i.e. 10 *
30 = 300.
The Rank property of a jagged array is always 1, but a
multidimensional array can have any rank. The GetLength method of any
array can be used to get the length of each dimension. For the
multidimensional array in this example mult.GetLength(1) returns 30.
Indexing the multidimensional array is faster e.g. given the
multidimensional array in this example mult[1,7] = 30 * 1 + 7 = 37,
get the element at that index 37. This is a better memory access
pattern because only one memory location is involved, which is the
base address of the array.
A multidimensional array therefore allocates a continuous memory
block, while a jagged array does not have to be square like. e.g.
jagged1.Length does not have to equal jagged[2].Length which would
be true for any multidimensional array.
Update:
One major difference between the multi and jagged array is that a multi must always be "square", meaning that any two indexes will have the same number of elements in their child arrays. A jagged array does not have this requirement. Take a look at the code below:
var jagged = new int[3][]; //not defining the size of the child array...
var multi = new int[3,8]; //defining a 3x8 "square"
var multiBad = new int[3,]; //Syntax error!
var jaggedSquare= new int[3][8]; //another 3x8 "square"
The former is a two dimensional array. The latter is an array whose elements are also arrays.
The first is for a multidimentional array
the second is for array of arrays
I have a code that looks like (more or less) :
public void INeedHolidaysNow(double[,]){
//... Code to take a break from coding and fly to Hawaii
}
double[][] WageLossPerVacationDay = new double[10][5];
INeedHolidays(WageLossPerVacationDay); // >>throws the Exception in the Title
I found the solution on this post which consists in looping rather thant trying a savage cast
So my question is : WHY ? what happens behind the scenes in the memory allocation that prevents what may seem - at least at first glance, to be a feasible cast ? I mean structurally, both expression seem to be quite identic. What is it that I am missing here ?
EDIT:
I have to use "double[ ][ ]" as it is provided by an external library.
One is a jagged array, the other is one big block.
double[][] is an array that contains arrays of double. Its form is not necessarily rectangular. In c terms its similar to a double**
double[,] is just one big block of memory, and it is always rectangular. In c terms it's just a double* where you use myArray[x+y*width] to access an element.
One is called multidimensional array (double[*,*]) and other is called jagged array (double[][]).
Here is a good discussion over differences between them.
What is differences between Multidimensional array and Array of Arrays in C#?
Quite simply, [,] arrays (2D arrays) and [][] arrays (jagged arrays) aren't the same.
A [,] array can be visually represented by a rectangle (hence it's also known as a rectangular array), while a [][] array is a 1D array that contains other 1D arrays.
It wouldn't make much sense to be able to cast one to the other.
You should define your double array like this:
double[,] WageLossPerVacationDay = new double[3, 5];
Then it should work!
hth