Allocate N elements

monarch_dodra monarchdodra at gmail.com
Mon Jul 15 08:44:14 PDT 2013


On Monday, 15 July 2013 at 13:13:42 UTC, bearophile wrote:
> Output:
> 512 1019
> 512 1019
> 512 0
>
> But that (of new arrays) is a bad design, it wastes too much 
> memory, and I think it should be fixed. In Python this doesn't 
> overallocate:

So what? The only thing you showed, is that minimallyInitialized 
doesn't know how much it allocated. If you allocate 513 elements 
with malloc, you'll way over allocate too. What's your point?

//--------
import std.stdio, core.memory;

void main()
{
     auto u = GC.qalloc(513);
     writeln(u.size); //print 1024. Oops.
}
//--------

You'll waste memory either way. The only difference is a 1-2 byte 
difference for arrays smaller than 2K, and 16 bytes for arrays 
larger than 2K.

The comparison is very unfair, and the wasted room is minimal. 
It's just more visible... yet more exploitable. Dynamic GC arrays 
have a tendency to grow in-place, and use all their capacity, 
when malloc always eagerly relocates.

To answer the original question:

> Is there no way (besides the ugly malloc or any wrappers) to 
> allocate _exactly_ N elements at runtime (no static array)?
> I tried

No. *EVEN* with an "ugly malloc", you'll still over allocate (see 
above).

Hell, at the end of the day, it's even worst, because you 
over-allocate, yet you don't know it, nor exploit the 
over-allocated data (unless you *very* manually use qalloc).

> Another question:
> I have this code:
> [...]
> Is it possible to prohibit that the slice is resized,
> to avoid GC allocations?

No. The only way this works is *if* there is a GC to safety net 
catch you if relocation must occur. That said, you can very 
easily write your own:
//----
//Disclaimer: VERY unsafe.
ref T[] unsafeAppend(T, U)(ref T[] arr, U u)
{
     immutable len = arr.length;
     arr.ptr[len] = u;
     arr = arr[0 .. len + 1];
}
//----
void main()
{
     auto u = GC.qalloc(512);
     int[] arr = (cast(int*)u.base)[0 .. 0];
     arr.unsafeAppend(1).unsafeAppend(2).unsafeAppend(3).writeln();
}
//----

Disclaimer: This will give you 0 overflow protection. Also, do 
NOT use this with GC arrays: The added elements will not be 
"seen" by the GC, and will also be clobbered by normal appends.


More information about the Digitalmars-d-learn mailing list