Resizing an array: Dangerous? Possibly buggy?

Steven Schveighoffer schveiguy at yahoo.com
Wed Mar 9 05:27:24 PST 2011


On Wed, 09 Mar 2011 06:41:54 -0500, %u <wfunction at hotmail.com> wrote:

> Increasing the sizes of an array has always given me the shivers, as
> beautiful as it is.

Since dmd around 2.042, array resizing and memory management has been  
extremely safe.  It should be very difficult for you to get into trouble.

>
> Could someone explain why this code behaves the way it does?
>
>     string s = "1234";
>     s.length = 7;
>     writefln("\"%s\"", s);
>
> prints:  "1234���"
>
> Given that it makes no sense to extend a const-size array, shouldn't
> there be a run-time check on the new size of the array, so that it
> throws whenever it's bigger than the current size?

A string is an immutable(char)[], it is not a fixed size.

Try this, and you will get an error:

int[5] x;
x.length = 7;

I will also point out that setting the length of a string is not a useful  
thing -- once the elements are added, they are set in stone (immutable),  
so essentially, you just added 4 unchangeable chars of 0xff.  It's better  
to append to a string, which will do it in place if possible.

> Also, another issue:
>
> Let's say you have an array that you dynamically resize (meaning you
> grow and shrink it a lot of times). In fact, let's say you have:
>     int[] arr = new int[1024 * 1024];
> and then you decide, hey, that's too big for how much space I
> actually needed:
>     arr.length = 5;
>
> Can the rest of the array be garbage collected?

No.  An array is one contiguous memory-allocated block.  It cannot be  
partially collected.

>     a. If the answer is "yes", then how does the GC know?
>     b. If the answer is "no", then doesn't that:
>        (1) Mean that we can have memory leaks?

Somewhat, as long as you keep a reference to that small array.  But once  
that array is unreferenced, the memory should be collected.

Note that if you do know that you are holding lots of memory with a small  
array, you can do something like this:

arr = arr[0..5].dup;

and this makes a copy just large enough to hold the 5 elements.  The  
original 1MB array should be collected.

>        (2) Mean that we still need an ArrayList!(T) type?

It depends on what you want to do, and how ArrayList is implemented.  In  
dcollections, ArrayList stores its elements in one contiguous memory  
block, just like an array.

-Steve


More information about the Digitalmars-d mailing list