[Issue 10593] New: array's reserve/capacity go haywire if length has been changed prior

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed Jul 10 03:45:33 PDT 2013


http://d.puremagic.com/issues/show_bug.cgi?id=10593

           Summary: array's reserve/capacity go haywire if length has been
                    changed prior
           Product: D
           Version: unspecified
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: critical
          Priority: P2
         Component: druntime
        AssignedTo: nobody at puremagic.com
        ReportedBy: monarchdodra at gmail.com


--- Comment #0 from monarchdodra at gmail.com 2013-07-10 03:45:32 PDT ---
On a win32 install on win7 64.

Array size must be bigger than 2047.

Not sure who is failing here (reserve? capacity?) but there is a big
discrepancy between the two. It may and/or may not also make subsequent appends
fail, or behave erratically.

My tests show capacity failing to report correctly. relocation being
indeterminate (I know it is not determinate behavior, but there's stink in my
tests), and reserve going out of control...

This is my test program:

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

void main()
{
    enum M = 2047;
    enum N = 4080;
    //Basic case, everything works correctly
    {
        ubyte[] a = new ubyte[](M);
        writefln("a.capacity before: %s", a.capacity);      //4079
        writefln("a.reserve(%s): %s", N, a.reserve(N)); //8175
        writefln("a.reserve(%s): %s", N, a.reserve(N)); //8175
        writefln("a.capacity after:  %s", a.capacity);      //8175
        auto b = a;
        b.length = N;
        writefln("Relocation after append?  %s", a.ptr !is b.ptr); //false
    }
    writeln();

    {
        ubyte[] a = new ubyte[](M);
        a ~= 1; // <= This little bastard here >:(
        writefln("a.capacity before: %s", a.capacity); //4079
        writefln("a.reserve(%s): %s", N, a.reserve(N)); //8175
        writefln("a.capacity after: %s", a.capacity); //4079 !!!
        auto b = a;
        b.length = N;
        writefln("Relocation after append? %s", a.ptr !is b.ptr); //false
    }
    writeln();

    {
        ubyte[] a;
        a.length = M; // <= This little bastard here >:(
        writefln("a.capacity before: %s", a.capacity); //4079
        writefln("a.reserve(%s): %s", N, a.reserve(N)); //8175
        writefln("a.capacity after: %s", a.capacity); //4079 !!!
        auto b = a;
        b.length = N;
        writefln("Relocation after append? %s", a.ptr !is b.ptr); //false
    }
    writeln();

    {
        ubyte[] a;
        a.length = M;
        writefln("a.reserve(%s): %s", N, a.reserve(N)); //8175
        writefln("a.reserve(%s): %s", N, a.reserve(N)); //12271 !!!
        writefln("a.reserve(%s): %s", N, a.reserve(N)); //16367 !!!
        writefln("a.reserve(%s): %s", N, a.reserve(N)); //20463 !!!
        writefln("a.capacity after: %s", a.capacity); //4079 !!!
    }
    writeln();
}
//----

And corresponding output (!!! added manually).

//----
a.capacity before: 4079
a.reserve(4080): 8175
a.reserve(4080): 8175
a.capacity after:  8175
Relocation after append?  false

a.capacity before: 4079
a.reserve(4080): 8175
a.capacity after: 4079
Relocation after append? false

a.capacity before: 4079
a.reserve(4080): 8175
a.capacity after: 4079
Relocation after append? false

a.reserve(4080): 8175
a.reserve(4080): 12271
a.reserve(4080): 16367
a.reserve(4080): 20463
a.capacity after: 4079
//----

To trigger, M must be at least as big as 2047, and N must be enough to require
work.

Marking as critical, as this is really a core feature of D, and *really*
getting in the way of some of my array/appender fixes.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list