Best properly way to destroy a 2 dimensional array?

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Apr 7 09:13:59 PDT 2016


On 4/6/16 3:54 PM, Jonathan Villa wrote:
> I wrote a little program that given some number it generates a list of
> different combinations (represented by a ubyte array), so in the end my
> function with name GenerateCombinations(int x) returns a ubyte[][] (list
> of arrays of ubytes).
>
> Now the problem is, the quantity of combinations generated are pow(2,
> `x`), thus, giving 20 it returns me a list of 1_048_576 arrays of ubyte,
> every array has length of `x` so, in the end this function allocates
> (seeing the Windows Task Manager) 42 MB of data after input `20` the
> first time.
>
> When the list is ready it prints the quantity of combinations given
> (combinations.length), after that I added a foreach(ubyte[] a;
> combinations) calling destroy to every array and then
> destroy(combinations), and before to re-input a new number to generate a
> new combination list I call GC.Collect() and GC.minimize().
>
> My question is if I'm doing good calling destroy to those arrays,
> because I don't see any change in the quantity of memory the program is
> using: In the start it uses 1496 KB, after input `20` it now have 43000
> KB (approx.) and if I input again 20 then it sums up to 90000 KB.
>
> In the end I don't see some kind of real memory free. I'm doing
> something wrong?
> That's the reason I'm asking for your advice.
>
> PD: All arrays are constructed with the `new` expression.
> PD2: Don't ask me why I don't better do an `int count` instead of
> constructing arrays, this little program is going to be part of a more
> huge application and I need the combination list.
>
> Regards. JV

You are likely running into the GC being conservative. You are also 
possibly running into an issue where you are expecting the compiler to 
do something with the stack where it may do something else. A classic 
question that is asked on D forums all the time is why when you null 
some variable and then call GC collect, the memory isn't collected. The 
answer is because quite possibly the value is still in a register, and 
the registers must be scanned too.

As for conservatism, if you generate a 1-million element array of 
pointers (each element has a pointer in it), then you have some random 
stack variable that "happens" to point into that giant array (more 
likely in 32-bit systems), then both the array, and all it's pointing at 
gets saved.

Note that destroying an array is equivalent to setting it to null. It 
doesn't write any data to the array itself.

Ironically, your example of this:

foreach(ubyte[] a; combs) destroy(a);

does absolutely nothing. Because all you are doing is setting a to null, 
and a is a local variable.

The only thing that could make a difference is destroying combs, which 
is equivalent to setting combs to null. But like I said, it's possible 
there is still a pointer in registers, or that some other stack variable 
points at your huge array.

-Steve


More information about the Digitalmars-d-learn mailing list