Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can arrays not be trimmed?

On the MSDN Documentation site it says the following about the Array.Resize method:

If newSize is greater than the Length of the old array, a new array is allocated and all the elements are copied from the old array to the new one.

If newSize is less than the Length of the old array, a new array is allocated and elements are copied from the old array to the new one until the new one is filled; the rest of the elements in the old array are ignored.

An array is a sequence of adjoined memory blocks. If we need a bigger array I understand that we cannot add memory to it since the memory next to it may already be claimed by some other data. So we have to claim a new sequence of adjoined memory blocks with the desired bigger size, copy our entries there and remove our claim of the old space.

But why create a new array with smaller size? Why can the array not just remove its claim of the last memory blocks? Then it would be an O(1) operation instead of O(n), as it is now.

Does it have something to do with how the data is organized on a computer architectural or physical level?

like image 710
Kjara Avatar asked Jul 19 '16 08:07

Kjara


People also ask

Can you resize an array?

You cannot resize an array in C#, but using Array. Resize you can replace the array with a new array of different size.

How do you shorten the length of an array?

You can't change the length of an array object once it's created. Here's an excerpt from JLS 10.2. Array Variables: Once an array object is created, its length never changes.

How do you prevent the array from being modified?

We can prevent mutation of objects and arrays using the Object. freeze() JavaScript function. We pass the desired object or array as an argument to this function, which later prevents any change to the object's or array's data.


1 Answers

Unused memory is not actually unused. It is the job of any heap implementation to keep track of holes in the heap. At a minimum, the manager needs to know the size of the hole and needs to keep track of their location. That always costs at least 8 bytes.

In .NET, System.Object plays a key role. Everybody knows what it does, what isn't so obvious that it continues to live on after an object is collected. The two extra fields in the object header (syncblock and type handle) then turn into a backward and forward pointer to the previous/next free block. It also has a minimum size, 12 bytes in 32-bit mode. Guarantees that there is always enough space to store the free block size after the object is collected.

So you probably see the problem now, reducing the size of an array does not guarantee that a hole is created that's big enough to fit those three fields. Nothing it could do but throw a "can't do that" exception. Also depends on the bitness of the process. Entirely too ugly to consider.

like image 80
Hans Passant Avatar answered Oct 18 '22 05:10

Hans Passant