www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Question about dynamic arrays and slices

reply Ary Borenszweig <ary esperanto.org.ar> writes:
Hi,

I just read this nice article about slices: 
http://dlang.org/d-array-article.html

So I tried this code to see if I understood it correctly:

---
import std.stdio;

void main() {
   auto a = new int[5];
   auto b = a;

   a[0] = 1;

   for(auto i = 0; i < 100; i++) {
     a ~= 0;
   }

   a[0] = 2;

   writefln("a[0] = %d", a[0]);
   writefln("b[0] = %d", b[0]);
}
---

This prints:

a[0] = 2
b[0] = 1

That is, "a" was resized to a point where it needed to reallocate its 
contents. "b" still holds a reference to the old data. When, after the 
for loop, I change a's data, b's data doesn't change.

Is this expected behaviour?

How can I safely pass around a dynamic array without being afraid 
someone will keep an old copy of the data?
Jan 30 2014
next sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
 This prints:

 a[0] = 2
 b[0] = 1

 That is, "a" was resized to a point where it needed to 
 reallocate its contents. "b" still holds a reference to the old 
 data. When, after the for loop, I change a's data, b's data 
 doesn't change.

 Is this expected behaviour?
That's how it is.
 How can I safely pass around a dynamic array without being 
 afraid someone will keep an old copy of the data?
I don't understand your exact requirements. Do you want to make sure that everyone sees the updates to the array, even after a relocation?
Jan 30 2014
prev sibling next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 30 January 2014 at 10:43:55 UTC, Ary Borenszweig 
wrote:
 Hi,

 I just read this nice article about slices: 
 http://dlang.org/d-array-article.html

 So I tried this code to see if I understood it correctly:

 ---
 import std.stdio;

 void main() {
   auto a = new int[5];
   auto b = a;

   a[0] = 1;

   for(auto i = 0; i < 100; i++) {
     a ~= 0;
   }

   a[0] = 2;

   writefln("a[0] = %d", a[0]);
   writefln("b[0] = %d", b[0]);
 }
 ---

 This prints:

 a[0] = 2
 b[0] = 1

 That is, "a" was resized to a point where it needed to 
 reallocate its contents. "b" still holds a reference to the old 
 data. When, after the for loop, I change a's data, b's data 
 doesn't change.

 Is this expected behaviour?

 How can I safely pass around a dynamic array without being 
 afraid someone will keep an old copy of the data?
pass the array by ref, or make a wrapper struct that holds a pointer to a slice, or a wrapper class that holds the slice. Alternatively, make a wrapper struct that disallows the append operator and always use std.array.refAppender
Jan 30 2014
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 30 January 2014 at 12:50:34 UTC, John Colvin wrote:
 On Thursday, 30 January 2014 at 10:43:55 UTC, Ary Borenszweig 
 wrote:
 Hi,

 I just read this nice article about slices: 
 http://dlang.org/d-array-article.html

 So I tried this code to see if I understood it correctly:

 ---
 import std.stdio;

 void main() {
  auto a = new int[5];
  auto b = a;

  a[0] = 1;

  for(auto i = 0; i < 100; i++) {
    a ~= 0;
  }

  a[0] = 2;

  writefln("a[0] = %d", a[0]);
  writefln("b[0] = %d", b[0]);
 }
 ---

 This prints:

 a[0] = 2
 b[0] = 1

 That is, "a" was resized to a point where it needed to 
 reallocate its contents. "b" still holds a reference to the 
 old data. When, after the for loop, I change a's data, b's 
 data doesn't change.

 Is this expected behaviour?

 How can I safely pass around a dynamic array without being 
 afraid someone will keep an old copy of the data?
pass the array by ref, or make a wrapper struct that holds a pointer to a slice, or a wrapper class that holds the slice. Alternatively, make a wrapper struct that disallows the append operator and always use std.array.refAppender
woops, sorry that last one doesn't help.
Jan 30 2014
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 30 Jan 2014 05:43:55 -0500, Ary Borenszweig <ary esperanto.org.ar>  
wrote:

 Hi,

 I just read this nice article about slices:  
 http://dlang.org/d-array-article.html

 So I tried this code to see if I understood it correctly:

 ---
 import std.stdio;

 void main() {
    auto a = new int[5];
    auto b = a;

    a[0] = 1;

    for(auto i = 0; i < 100; i++) {
      a ~= 0;
    }

    a[0] = 2;

    writefln("a[0] = %d", a[0]);
    writefln("b[0] = %d", b[0]);
 }
 ---

 This prints:

 a[0] = 2
 b[0] = 1

 That is, "a" was resized to a point where it needed to reallocate its  
 contents. "b" still holds a reference to the old data. When, after the  
 for loop, I change a's data, b's data doesn't change.

 Is this expected behaviour?
Yes, it is intrinsic on how slices and arrays work.
 How can I safely pass around a dynamic array without being afraid  
 someone will keep an old copy of the data?
You can't. Why is that important? The use case (or case that you are troubled by) would help to explain I think. -Steve
Jan 30 2014