Arrays, copied or referenced?
Kirk McDonald
kirklin.mcdonald at gmail.com
Sun Aug 5 15:34:55 PDT 2007
Audun Wilhelmsen wrote:
> Hey..
>
> Take this code:
> --------------------------
> import std.stdio;
>
> int[] arrayTest(int[] a) {
> a.length = 5;
> a[4] = 42;
> return a;
> }
>
> int main(char[][] args) {
> int[10] foobar;
> foobar[4] = 2;
> arrayTest(foobar);
> writefln("%d", foobar[4]);
> return 0;
> }
> --------------------------
> It prints out "42".
> Now replace the line "a.length = 20", and it prints out "2".
>
> Is that the way it's supposed to behave?
>
> Audun Wilhelmsen
> NTNU, Norway
I've set the Followup-To to digitalmars.D.learn.
This is perhaps a tricky subject. The answer is yes, that is the correct
behavior.
Let me copy your function again:
int[] arrayTest(int[] a) {
a.length = 5;
a[4] = 42;
return a;
}
Dynamic arrays in D are a struct that looks something like this:
struct dyn_array {
void* ptr;
size_t length;
}
When you pass an array to arrayTest, it passes this struct by value.
When you say:
a.length = 5;
There is some logic that it does behind the scenes. If the new length is
shorter than the old length, it simply changes the length attribute of
the struct, and the pointer refers to the same chunk of memory that it
did before. If the new length is longer than the chunk of memory to
which ptr points (which in this example is a static array in main, so
this is always true if you make the length longer), it will allocate a
new array on the heap, and copy the array contents into it.
Thus, when you say 'a.length = 20', you're suddenly referring to a
different chunk of memory. This allocation is not always guaranteed to
happen, which is why I said this is a tricky subject.
To get actual reference semantics, you should use something like this:
void arrayTest(ref int[] a) {
a.length = 20;
a[4] = 42;
}
void main() {
int[] foobar = new int[](10);
foobar[4] = 2;
arrayTest(foobar);
writefln("%d", foobar[4]);
}
Note the 'ref' in arrayTest's parameter. Also note that it's passing an
int[] and not an int[10] to arrayTest: You can't assign a dynamic array
to a static array.
However, if you're just passing the contents of the array to a function,
and not modifying the array itself, passing a regular int[] will get you
all of the reference semantics you need.
--
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org
More information about the Digitalmars-d
mailing list