Arrays of structs
BBasile via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Aug 27 03:36:47 PDT 2015
On Thursday, 27 August 2015 at 10:05:31 UTC, John Burton wrote:
> I'm a c++ programmer trying to understand how memory allocation
> works in D.
>
> I created a struct and added a destructor to it. My
> understanding is that structs have deterministic destructors -
> they are called when the struct goes out of scope (unless it is
> allocated with new).
>
> Now if I put instances of the struct in a fixed size array
>
> data[6] d;
> d[3] = data(1, 2, 3);
>
> then the destructor on all the contents is called when the
> array goes out of scope.
>
> However if I add them to a dynamic array...
>
> data[] d;
> d ~= data(1, 2, 3)
>
> Then the destructor appears to be called at some random time
> later. So it looks like it's the garbage collection that is
> doing this. That seems to go against the specification of how
> struct works... I'm not creating the item with "new" and as far
> as I can tell the array is storing instances of objects, not
> pointers to objects?
>
> Is my understanding correct?
> Is it documented anywhere how memory allocation works for this?
>
> Is a dynamic array in fact storing an array of GC'd pointers to
> the structs? Or something else...
With a local scope,
- a static array of data will have the destructors called on
exit because memory for the memebers is not allocated on the
GC-hep but on the stack frame.
- a dynamic array of data will have the destructors called on
next GC collection because the memory for the memebers is
allocated on the GC-heap.
- a dynamic array of pointer to data will have the destructors
called on next GC collection because the memory for the memebers
is allocated on the GC-heap.
you can see this in this small program. deactivate to commented
GC.collect to see the difference:
---
struct Foo {
long v0, v1;
~this(){writeln(typeof(this).stringof);}
}
void localteststatic(){
Foo[1] fl;
}
void localtestdynamic1(){
Foo[] fl;
fl.length = 1;
fl.length = 0;
}
void localtestdynamic2(){
Foo* [] fl;
fl ~= new Foo(1);
}
void localtestdynamic3(){
Foo[] fl;
fl.length = 1;
fl.length = 0;
}
void main(string[] args)
{
import core.memory;
localteststatic; writeln("done local test static");
localtestdynamic3; writeln("done local test dynamic 3");
//GC.collect;
localtestdynamic1; writeln("done local test dynamic 1");
//GC.collect;
localtestdynamic2; writeln("done local test dynamic 2");
//GC.collect;
}
---
Also for the second question:
* fl[]: each element has a .sizeof 16 (long .size_of * 2)
* fl* []: each element has a .sizeof size_t.sizeof (this a
pointer so 4 or 8).
More information about the Digitalmars-d-learn
mailing list