Jake Manet
Jake Manet

Reputation: 1252

Why arrays needs dimension set at define time?

I am just wondering, why can't we just define something like this:

int[] arr = new int[];
arr[0] = 1;

Like a list, to resize automatically. What i want to know is why is this impossible and we need to set every time the size in the following way:

int[] arr = new int[1];
arr[0] = 1;

Upvotes: 4

Views: 224

Answers (5)

NPSF3000
NPSF3000

Reputation: 2451

My guess would be 'because it's specified this way' - which happens gives arrays specific performance characteristics and optimisation capabilities which are highly desirable. While these advantages would have been noted by the designers, and be present in influencing languages which also use similar constructs (C, C++, Java - Footnote 1), they honestly could have defined it to do anything.

List<T> for example, has to resize the internal array usually allocating more memory than necessary (unless you happen to use just as much as been allocated) as well as creating garbage.

1.8 of the C# language specification has the following:

An array is a data structure that contains a number of variables that are accessed through computed indices. The variables contained in an array, also called the elements of the array, are all of the same type, and this type is called the element type of the array.

Array types are reference types, and the declaration of an array variable simply sets aside space for a reference to an array instance. Actual array instances are created dynamically at run-time using the new operator. The new operation specifies the length of the new array instance, which is then fixed for the lifetime of the instance. The indices of the elements of an array range from 0 to Length - 1. The new operator automatically initializes the elements of an array to their default value, which, for example, is zero for all numeric types and null for all reference types.

Furthermore, not mentioned by anyone-else array bounds checking is considered a 'software engineering principle' - as stated when describing their design goals in the ECMA 334 Spec:

The language, and implementations thereof, should provide support for software engineering principles such as strong type checking, array bounds checking, detection of attempts to use uninitialized variables, and automatic garbage collection. Software robustness, durability, and programmer productivity are important.

Footnote 1 - Introduction of C# language spec:

C# (pronounced “See Sharp”) is a simple, modern, object-oriented, and type-safe programming language. C# has its roots in the C family of languages and will be immediately familiar to C, C++, and Java programmers.

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1500225

List<T>'s resizing is based on creating a new array behind the scenes when it needs to.

Think about what the underlying implementation looks like here. When you allocate an array, it reserves a chunk of memory, and the reference effectively points straight at that memory. If you need to store more values than you've reserved, you need to allocate more memory, somewhere else... but you can't change the reference to refer to that new memory, because those references are spread all over the place. (The array doesn't know what's referring to it.)

The obvious way around this is to have a level of indirection - so that the initial reference is to an object which keeps track of where the real data is stored, so it can reallocate when it wants to. That's exactly what List<T> does... but it does mean there's that extra level of indirection. That has a cost in efficiency, partly as you may well have the actual data a long way in memory from the List object itself, which isn't good for caching... and simply going through an extra level of indirection has a cost in itself.

Basically if you want a dynamically sized collection, use List<T> - that's what it's there for. If you know the final size from the start and want to benefit from the "nearer to the metal" aspect of arrays, use those instead.

Arrays are a relatively low level concept - if you want a high level abstraction, use one...

Upvotes: 12

dcastro
dcastro

Reputation: 68640

Because arrays are contiguous in memory, you have to allocate enough memory for its contents when you create it.

Say you have an array with 100 items in it. Now you add 1 more, and you have to claim the memory address right after the 100th item. What if that address is already being used?

That's why you can't dynamically resize an array.

Upvotes: 7

ManOnAMission
ManOnAMission

Reputation: 1043

Because an array's size is static by defintion and not dynamic.

If you want a dynamically sized collection, there are others, like the list you mentioned, available.

What you can do though is to delay the declaration of the size of the array:

int[] numbers;
numbers = new int[10];  
numbers = new int[20];  

Upvotes: 1

Patrick Hofman
Patrick Hofman

Reputation: 156948

That is because arrays allocate memory, and the framework needs to know how much.

If you want a dynamic sizing 'array', use List.

A list actually wraps an array. When adding more items then in current array, a new array (usually double sized) is created, old items are moved to the new array. Deleting goes the other way around.

Upvotes: 1

Related Questions