digitalmars.D.learn - back to arays
- Max Samuha <maxter i.com.ua_spamless> May 15 2006
- "Regan Heath" <regan netwin.co.nz> May 15 2006
- Derek Parnell <derek psych.ward> May 15 2006
- Tom S <h3r3tic remove.mat.uni.torun.pl> May 15 2006
- "Derek Parnell" <derek psych.ward> May 15 2006
- Bruno Medeiros <brunodomedeirosATgmail SPAM.com> May 15 2006
- Max Samuha <maxter i.com.ua_spamless> May 15 2006
- Chris Nicholson-Sauls <ibisbasenji gmail.com> May 15 2006
- Bruno Medeiros <brunodomedeirosATgmail SPAM.com> May 15 2006
- Tom S <h3r3tic remove.mat.uni.torun.pl> May 15 2006
- Oskar Linde <oskar.lindeREM OVEgmail.com> May 15 2006
- James Pelcis <jpelcis gmail.com> May 15 2006
- Max Samuha <maxter i.com.ua_spamless> May 17 2006
- "Unknown W. Brackets" <unknown simplemachines.org> May 17 2006
- Derek Parnell <derek psych.ward> May 17 2006
- Bruno Medeiros <brunodomedeirosATgmail SPAM.com> May 18 2006
I thought array references are similar to object references like in C# (actually, thay are object references in C#) and that was my mistake: int[] a = new int[20]; int[] b = a; a.length = 40; // a is copied and b is not updated to point to a's data; Does it mean that anytime i change an array, i have to manually update all references to it or should i wrap my array in an Array class so that all references to any instance of that array remain valid? If the question have been already discussed please refer me to the right thread. Thanks
May 15 2006
On Mon, 15 May 2006 10:05:22 +0300, Max Samuha <maxter i.com.ua_spamless> wrote:I thought array references are similar to object references like in C# (actually, thay are object references in C#) and that was my mistake: int[] a = new int[20]; int[] b = a; a.length = 40; // a is copied and b is not updated to point to a's data; Does it mean that anytime i change an array, i have to manually update all references to it or should i wrap my array in an Array class so that all references to any instance of that array remain valid? If the question have been already discussed please refer me to the right thread. Thanks
The D philosophy is "copy on write". Whenever you have several references to the same data and you decide to write to the data, you should make a copy and write to the copy. If you want to constantly have several references to the same data then yes, you will have to update the references whenever you make change or write a class to handle that for you. Regan
May 15 2006
On Mon, 15 May 2006 10:05:22 +0300, Max Samuha wrote:I thought array references are similar to object references like in C# (actually, thay are object references in C#) and that was my mistake: int[] a = new int[20]; int[] b = a; a.length = 40; // a is copied and b is not updated to point to a's data; Does it mean that anytime i change an array, i have to manually update all references to it or should i wrap my array in an Array class so that all references to any instance of that array remain valid? If the question have been already discussed please refer me to the right thread. Thanks
I assume for some valid reason you want this behaviour... int[] a = new int[20]; int[] b = a; int[] c = a; a[0] = 17; writefln("%s %s", b[0], c[0]); // Displays 17 17 The simplest way to do this is ... int[] a = new int[20]; int[]* b = &a; int[]* c = &a; a[0] = 17; writefln("%s %s", b[0], c[0]); // Displays 17 17 I'm not sure why one would need this behaviour though. Why do you need two identifiers in the same scope to reference the same data? -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 15/05/2006 5:49:08 PM
May 15 2006
Derek Parnell wrote:On Mon, 15 May 2006 10:05:22 +0300, Max Samuha wrote:I thought array references are similar to object references like in C# (actually, thay are object references in C#) and that was my mistake: int[] a = new int[20]; int[] b = a; a.length = 40; // a is copied and b is not updated to point to a's data; Does it mean that anytime i change an array, i have to manually update all references to it or should i wrap my array in an Array class so that all references to any instance of that array remain valid? If the question have been already discussed please refer me to the right thread. Thanks
I assume for some valid reason you want this behaviour... int[] a = new int[20]; int[] b = a; int[] c = a; a[0] = 17; writefln("%s %s", b[0], c[0]); // Displays 17 17
But... it will display '17 17'.The simplest way to do this is ... int[] a = new int[20]; int[]* b = &a; int[]* c = &a; a[0] = 17; writefln("%s %s", b[0], c[0]); // Displays 17 17
Nope, the earlier one :) As I understand it, he'd like this code: # int[] a = new int[20]; # int[] b = a; # b.length = 10; # writefln("%s %s", a.length, b.length); to output '20 20'. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d-pu s+: a-->----- C+++$>++++ UL P+ L+ E--- W++ N++ o? K? w++ !O !M V? PS- PE- Y PGP t 5 X? R tv-- b DI- D+ G e>+++ h>++ !r !y ------END GEEK CODE BLOCK------ Tomasz Stachowiak /+ a.k.a. h3r3tic +/
May 15 2006
On Mon, 15 May 2006 20:24:39 +1000, Tom S <h3r3tic remove.mat.uni.torun.pl> wrote:Derek Parnell wrote:On Mon, 15 May 2006 10:05:22 +0300, Max Samuha wrote:I thought array references are similar to object references like in C# (actually, thay are object references in C#) and that was my mistake: int[] a = new int[20]; int[] b = a; a.length = 40; // a is copied and b is not updated to point to a's data; Does it mean that anytime i change an array, i have to manually update all references to it or should i wrap my array in an Array class so that all references to any instance of that array remain valid? If the question have been already discussed please refer me to the right thread. Thanks
int[] a = new int[20]; int[] b = a; int[] c = a; a[0] = 17; writefln("%s %s", b[0], c[0]); // Displays 17 17
But... it will display '17 17'.The simplest way to do this is ... int[] a = new int[20]; int[]* b = &a; int[]* c = &a; a[0] = 17; writefln("%s %s", b[0], c[0]); // Displays 17 17
Nope, the earlier one :) As I understand it, he'd like this code: # int[] a = new int[20]; # int[] b = a; # b.length = 10; # writefln("%s %s", a.length, b.length); to output '20 20'.
That's what you get while trying to rush out of the office, late again for dinner. You are right. Here is my improved attempt and what I was trying to say earlier... import std.stdio; void main() { int[] a; int[]* b; int[]* c; b = &a; c = &a; a.length= 40; a[0] = 17; writefln("%d %d", c.length, b.length); writefln("%d %d", *c[0], *b[0]); } ------------------------- This displays 40 40 17 17 ------------------------- But I still don't know why one would want to do this? -- Derek Parnell Melbourne, Australia
May 15 2006
Derek Parnell wrote:I'm not sure why one would need this behaviour though. Why do you need two identifiers in the same scope to reference the same data?
Derek Parnell wrote:But I still don't know why one would want to do this?
I'll bet the identifiers are on the same scope just for simplification purposes. The case were you would want to have a dyn array to behave "wholly" like a reference type is quite common and necessary, just like associative arrays are now "wholly" a reference type. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 15 2006
On Mon, 15 May 2006 23:08:26 +1000, "Derek Parnell" <derek psych.ward> wrote:void main() { int[] a; int[]* b; int[]* c; b = &a; c = &a; a.length= 40; a[0] = 17; writefln("%d %d", c.length, b.length); writefln("%d %d", *c[0], *b[0]); } ------------------------- This displays 40 40 17 17 ------------------------- But I still don't know why one would want to do this?
No, i certainly don't want to do this. I just expected from D's dynamic arrays what was described here in a more readable English as arrays being reference types. That's clearer now. Thanks
May 15 2006
Max Samuha wrote:On Mon, 15 May 2006 23:08:26 +1000, "Derek Parnell" <derek psych.ward> wrote:void main() { int[] a; int[]* b; int[]* c; b = &a; c = &a; a.length= 40; a[0] = 17; writefln("%d %d", c.length, b.length); writefln("%d %d", *c[0], *b[0]); } ------------------------- This displays 40 40 17 17 ------------------------- But I still don't know why one would want to do this?
No, i certainly don't want to do this. I just expected from D's dynamic arrays what was described here in a more readable English as arrays being reference types. That's clearer now. Thanks
I have made some similar mistakes before, to be sure. Essentially D's arrays are really structures, one of the fields of which being a pointer to the real data. Sometimes this means another array variable will be pointing to the same data, but this leaves you when you try to muck with the array. Although, in some (not all) cases you can get behavior like what you want by using inout parameters (or pointers), and in some other cases (still not all) you could probably use slice semantics. -- Chris Nicholson-Sauls
May 15 2006
Tom S wrote:As I understand it, he'd like this code: # int[] a = new int[20]; # int[] b = a; # b.length = 10; # writefln("%s %s", a.length, b.length); to output '20 20'.
You mean "to output '10 10'", no? -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 15 2006
Bruno Medeiros wrote:You mean "to output '10 10'", no?
Arrrgh you're right :S -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d-pu s+: a-->----- C+++$>++++ UL P+ L+ E--- W++ N++ o? K? w++ !O !M V? PS- PE- Y PGP t 5 X? R tv-- b DI- D+ G e>+++ h>++ !r !y ------END GEEK CODE BLOCK------ Tomasz Stachowiak /+ a.k.a. h3r3tic +/
May 15 2006
Max Samuha skrev:I thought array references are similar to object references like in C# (actually, thay are object references in C#) and that was my mistake: int[] a = new int[20]; int[] b = a; a.length = 40; // a is copied and b is not updated to point to a's data; Does it mean that anytime i change an array, i have to manually update all references to it or should i wrap my array in an Array class so that all references to any instance of that array remain valid? If the question have been already discussed please refer me to the right thread. Thanks
The behavior of D's built in arrays have been the cause of much confusion. D's arrays actually have a kind of schizophrenic nature. They are value types referring to some portion of memory, and as such, they are not pure arrays (of course a matter of interpretation), but rather array slices. On the other hand they support append operations, and automatically copy and reallocate the data when the length is increased, which doesn't make sense for a pure slice type. So in the sense of being arrays, D's arrays neither fulfill the expected semantics of being a value type nor a reference type. This will probably make many D users cringe, by my suggestion is to use an array wrapper type with reference semantics. Something like this: (untested and incomplete code) class Array(T) { T[] data; this() {} this(int n) { length(n); } this(T[] data) { this.data = data; } void length(size_t n) { data.length = n; } size_t length() { return data.length; } Array dup() { return new Array(data.dup); } T opIndex(size_t i) { return data[i]; } T opIndexAssign(T v, size_t i) { return data[i] = v; } T[] opSlice(size_t a, size_t b) { return data[a..b]; } int opApply(...) {...} } Usage: Array!(int) a = new Array!(int)(20); Array!(int) b = a; a.length = 40; // a is NOT copied and b is updated to point to a's data Properly implemented this will work as you expect with one caveat. There is no reference return type for opIndex, making arrays of structs somewhat inconvenient. I think you can find a proper implementation in the ancient DTL library. Regards, Oskar
May 15 2006
You can always "cheat" and do: alias a b; Max Samuha wrote:I thought array references are similar to object references like in C# (actually, thay are object references in C#) and that was my mistake: int[] a = new int[20]; int[] b = a; a.length = 40; // a is copied and b is not updated to point to a's data; Does it mean that anytime i change an array, i have to manually update all references to it or should i wrap my array in an Array class so that all references to any instance of that array remain valid? If the question have been already discussed please refer me to the right thread. Thanks
May 15 2006
There's one more question about arrays. From D specs:A pointer to the start of a garbage collected object need not be maintained if a pointer to the interior of the object exists. char[] p = new char[10]; char[] q = p[3..6]; // q is enough to hold on to the object, don't need to keep // p as well.
If the garbage collector moves data referenced by p, i guess all pointers to slices of p will be updated correctly. What if i set p to null or p goes out of scope and q is still reachable, will the memory (before q.ptr and after q.ptr + q.length - 1) that was pointed to by p be reclaimed by the garbage collector?
May 17 2006
I should note, currently, DMD's implementation won't move anything you're pointing to. And... as you probably know, memory is allocated in chunks from the operating system. Without making a copy, you can't deallocate just one part. So DMD won't currently. However, if the memory were to be copied I'd expect it to be perfectly reasonable that the GC might not keep the old array data (although that would certainly be non-trivial for the GC to do.) I wouldn't depend on it - and it seems brittle anyway, even if it were guaranteed. -[Unknown]There's one more question about arrays. From D specs:A pointer to the start of a garbage collected object need not be maintained if a pointer to the interior of the object exists. char[] p = new char[10]; char[] q = p[3..6]; // q is enough to hold on to the object, don't need to keep // p as well.
If the garbage collector moves data referenced by p, i guess all pointers to slices of p will be updated correctly. What if i set p to null or p goes out of scope and q is still reachable, will the memory (before q.ptr and after q.ptr + q.length - 1) that was pointed to by p be reclaimed by the garbage collector?
May 17 2006
On Wed, 17 May 2006 22:07:12 -0700, Unknown W. Brackets wrote:I should note, currently, DMD's implementation won't move anything you're pointing to.
Even if the length is increased beyond the size that has been allocated for a dynamic array? I thought that DMD allocated a new block of the right size and copied data from the old block to it then released the old block back to the GC. I think that if the length is decreased then no copying goes on and that no memory is released back to the GC, but can be later reused if the length then is increased anywhere up to the original allocation size. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 18/05/2006 3:20:14 PM
May 17 2006
Derek Parnell wrote:On Wed, 17 May 2006 22:07:12 -0700, Unknown W. Brackets wrote:I should note, currently, DMD's implementation won't move anything you're pointing to.
Even if the length is increased beyond the size that has been allocated for a dynamic array? I thought that DMD allocated a new block of the right size and copied data from the old block to it then released the old block back to the GC.
Yes, that's what it does, but that resizing results from an explicit programmer action, and not from the GC. When W. Brackets mentioned "DMD's implementation" I believe he meant the GC only, which, as is known, indeed doesn't currently move anything.I think that if the length is decreased then no copying goes on and that no memory is released back to the GC, but can be later reused if the length then is increased anywhere up to the original allocation size.
-- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 18 2006
Right, sorry if I was unclear. When you resize an array, it makes a copy - it still doesn't move anything. When I was talking about moving, I was meaning a compacting (defragmenting) garbage collector. DMD's garbage collector holds onto any pointer references which are still active, even if you change the length of a dynamic array - so that issue shouldn't affect this. For slices to work properly, the above must be guaranteed afaik. But holding onto the memory around said slices need not be guaranteed. PS: I've been called a lot of different things (Uncle Brackets, Big U, etc.), but I hadn't ever heard "W. Brackets". Heh. -[Unknown]Derek Parnell wrote:On Wed, 17 May 2006 22:07:12 -0700, Unknown W. Brackets wrote:I should note, currently, DMD's implementation won't move anything you're pointing to.
Even if the length is increased beyond the size that has been allocated for a dynamic array? I thought that DMD allocated a new block of the right size and copied data from the old block to it then released the old block back to the GC.
Yes, that's what it does, but that resizing results from an explicit programmer action, and not from the GC. When W. Brackets mentioned "DMD's implementation" I believe he meant the GC only, which, as is known, indeed doesn't currently move anything.
May 19 2006









"Regan Heath" <regan netwin.co.nz> 