www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 6153] New: Inserting to An Array!T inside an Array!(Array!T) causes a segfault.

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

           Summary: Inserting to An Array!T inside an Array!(Array!T)
                    causes a segfault.
           Product: D
           Version: D2
          Platform: x86_64
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: victor.v.carvalho gmail.com



PDT ---
Created an attachment (id=996)
testcase

See the attached test case. Running it causes a segfault on glibc.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 12 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6153


Andrei Alexandrescu <andrei metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
                 CC|                            |andrei metalanguage.com
         AssignedTo|nobody puremagic.com        |andrei metalanguage.com


-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 12 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6153


SomeDude <lovelydear mailmetrash.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lovelydear mailmetrash.com



PDT ---
The following works correctly:

import std.stdio;
import std.container;

int main() {
    alias Array!int Arr1D;
    alias Array!Arr1D Arr2D;

    auto arr1D = Arr1D();
    auto arr2D = Arr2D();

    writefln("arr1D %s of size = %d", arr1D, arr1D.length());
    arr1D.insert(1); 
    arr1D.insert(2);
    writefln("arr1D %s of size = %d", arr1D[0], arr1D.length());

    arr2D.insert(arr1D);
    writefln("arr2D %s of size = %d", arr2D, arr2D.length());
    writeln(arr2D[0][0], arr2D[0][1]);
    return 0;
}

It produces the output:
PS E:\DigitalMars\dmd2\samples> rdmd a.d
arr1D
Array!(int)(RefCounted!(Payload,cast(RefCountedAutoInitialize)0)(_RefCounted(null)))
of size = 0
arr1D 1 of size = 2
arr2D
Array!(Array!(int))(RefCounted!(Payload,cast(RefCountedAutoInitialize)0)(_RefCounted(A623F0)))
of size = 1
12
PS E:\DigitalMars\dmd2\samples>


However inserting ints in arr1D *after* having inserted it in arr2D produces
access violations:

import std.stdio;
import std.container;

int main() {
    alias Array!int Arr1D;
    alias Array!Arr1D Arr2D;

    auto arr1D = Arr1D();
    auto arr2D = Arr2D();
    arr2D.insert(arr1D);
    writefln("arr2D %s of size %d", arr2D[0], arr2D.length());

    arr2D[0].insert(1);
    arr2D[0].insert(2);
    writefln("array size after insert: %d", arr2D[0].length());
    //writeln(arr2D[0][0], arr2D[0][1]);
    return 0;
}

produces:
PS E:\DigitalMars\dmd2\samples> rdmd bug.d
arr2D
Array!(int)(RefCounted!(Payload,cast(RefCountedAutoInitialize)0)(_RefCounted(null)))
of size 1
array size after insert: 0
PS E:\DigitalMars\dmd2\samples>

It seems that the reason is, as long as arr1D has no elements inserted via
insert, it's not allocated and arr2D[0] is null.

See also issue 7901.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 24 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6153


SomeDude <lovelydear mailmetrash.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |iteronvexor gmail.com



PDT ---
*** Issue 7901 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 24 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6153


Matthias Walter <xammy xammy.info> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |xammy xammy.info



---
The reason for the failure is that for

arr2D[0].insert(1);

the opIndex() method is invoked which returns by value. In theory this is okay
since the array is stored by reference and the returned value contains a
reference to the payload data of the inner array.

What happens here is that arr2D[0] is uninitialized (the pointer to the
RefCounted object is null) and this guy is returned. It is then changed (the
insert method initializes the temporary and creates the ref-counted object with
the inserted content).

One way to resolve this is to make opIndex return a reference. Or is there an
alternative?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 18 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6153


Christophe Travert <christophe.travert normalesup.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |christophe.travert normales
                   |                            |up.org



2012-07-18 06:46:14 PDT ---

 The reason for the failure is that for
 
 arr2D[0].insert(1);
 
 the opIndex() method is invoked which returns by value. In theory this is okay
 since the array is stored by reference and the returned value contains a
 reference to the payload data of the inner array.
 
 What happens here is that arr2D[0] is uninitialized (the pointer to the
 RefCounted object is null) and this guy is returned. It is then changed (the
 insert method initializes the temporary and creates the ref-counted object with
 the inserted content).
 
 One way to resolve this is to make opIndex return a reference. Or is there an
 alternative?
I think both should be corrected: - uninitialised Arrays do not behave as reference values: you can copy them, change the copy, and this does not affect the original. This breaks the intended 'reference value' behavior. The cost of creating a payload for each empty Array may be compensated by not having to check the payload is initialised in each of Array's methods. - opIndex should return a reference. Any struct with a non-const method will suffer the same problem when 'array[i].method' is called: the method is called on a copy of the contained data. Note that Array!bool cannot return a reference to a bool, and can't be corrected the same way. I think this is not a problem, but I may miss something. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 18 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=6153


Andrei Alexandrescu <andrei erdani.com> changed:

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



PST ---
Works now, probably has been fixed along with other bugs. Feel free to reopen
if I missed something.

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