www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 4590] New: Spec incorrectly describes array appending and memory stomping

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4590

           Summary: Spec incorrectly describes array appending and memory
                    stomping
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: www.digitalmars.com
        AssignedTo: nobody puremagic.com
        ReportedBy: schveiguy yahoo.com


--- Comment #0 from Steven Schveighoffer <schveiguy yahoo.com> 2010-08-05
13:21:20 PDT ---
The following excerpt is from the arrays page:

------>8------

The .length property of a dynamic array can be set as the lvalue of an =
operator:

array.length = 7;

This causes the array to be reallocated in place, and the existing contents
copied over to the new array. If the new array length is shorter, only enough
are copied to fill the new array. If the new array length is longer, the
remainder is filled out with the default initializer.

To maximize efficiency, the runtime always tries to resize the array in place
to avoid extra copying. It will always do a copy if the new size is larger and
the array was not allocated via the new operator or a previous resize
operation.

This means that if there is an array slice immediately following the array
being resized, the resized array could overlap the slice; i.e.:

char[] a = new char[20];
char[] b = a[0..10];
char[] c = a[10..20];

b.length = 15;    // always resized in place because it is sliced
        // from a[] which has enough memory for 15 chars
b[11] = 'x';    // a[11] and c[1] are also affected

a.length = 1;
a.length = 20;    // no net change to memory layout

c.length = 12;    // always does a copy because c[] is not at the
        // start of a gc allocation block
c[5] = 'y';    // does not affect contents of a[] or b[]

a.length = 25;    // may or may not do a copy
a[3] = 'z';    // may or may not affect b[3] which still overlaps
        // the old a[3]

To guarantee copying behavior, use the .dup property to ensure a unique array
that can be resized.

These issues also apply to concatenating arrays with the ~ and ~= operators.

---------8<-------


There are several incorrect statements here, some are very old, some are
recently incorrect (as of 2.042).  I'll go through the changes I think should
be made:


------------------

- It will always do a copy if the new size is larger and the array was not
allocated via the new operator or a previous resize operation.

CHANGE TO =====>

+ It will always do a copy if the new size is larger and the array was not
allocated via the new operator or resizing in place would overwrite valid data
in the array.

----------------

- This means that if there is an array slice immediately following the array
being resized, the resized array could overlap the slice; i.e.:

< completely invalid example >

CHANGE TO =====>

+ For example:

char[] a = new char[20];
char[] b = a[0..10];
char[] c = a[10..20];
char[] d = a;

b.length = 15;    // always reallocates because extending in place would
                // overwrite other data in a.
b[11] = 'x';    // a[11] and c[1] are not affected

d.length = 1;
d.length = 20;    // also resizes, because doing this will overwrite a and c

c.length = 12;    // may reallocate in place if space allows, because nothing
was
                // allocated after c.
c[5] = 'y';    // may affect contents of a, but not b or d because those were
                // reallocated. 

a.length = 25;    // This always reallocates because if c extended in place,
then
                // extending a would overwrite c.  If c didn't reallocate in
                // place, it means there was not enough space, which will still
                // be true for a.
a[15] = 'z';    // does not affect c, because either a or c has reallocated.

------------------

- To guarantee copying behavior, use the .dup property to ensure a unique array
that can be resized.

- These issues also apply to concatenating arrays with the ~ and ~= operators.

CHANGE TO =====>

+ To guarantee copying behavior, use the .dup property to ensure a unique array
that can be resized. Also, one may use the phobos .capacity property to
determine how many elements can be appended to the array without reallocating.

+ These issues also apply to appending arrays with the ~= operator.  However,
concatenation with the ~ operator is not affected since concatenation
guarantees a reallocation.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 05 2010
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4590


Steven Schveighoffer <schveiguy yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


--- Comment #1 from Steven Schveighoffer <schveiguy yahoo.com> 2010-11-24
05:55:47 PST ---
Not sure why I didn't mark this as fixed...

Fixed in 2.048

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