The bug is similar to https://issues.dlang.org/show_bug.cgi?id=6998. Specifically, here is the code that can be used to demonstrate it. I'm using GDC 4.9.1 (according to gdc --version).

module badbh;

import std.container, std.string, std.stdio;

class Node {
  size_t val;
  Node next;

  this (size_t val) {
    this.val = val;
  }

  override string toString() {
    if (next is null) {
      return format("%s", val);
    } else {
      return format("%s, %s", val, next.toString());
    }
  }
}

void main () {
  //sets up the demo structure
  auto n = new Node(40);
  n.next = new Node(30);
  n.next.next = new Node(10);
  n.next.next.next = new Node(20);
  writeln(n); //should yield "40, 30, 10, 20"
  auto t2 = top2(n);
  writeln(n); //watch the segfaults
}

Node[] top2 (Node n) {
auto heap = BinaryHeap!(Array!Node, function bool (Node a, Node b){return a.val > b.val;})();
  Node[] nodes;
  auto ptr = n;
  while (ptr !is null) {
    heap.insert(ptr);
    ptr = ptr.next;
  }
  for (auto i = 0; i < 2; i++) {
    nodes ~= heap.front;
    heap.removeFront;
  }
  assert(nodes.length == 2);
  //some sanity checks to show my code isn't logically FUBAR
  assert(nodes[0] !is null);
  assert(nodes[1] !is null);
  assert(nodes[0].val == 10);
  assert(nodes[1].val == 20);
  return nodes;
}

The comments are self-explanatory. This destructive behaviour occurs *only* when the heap is in a different scope to the structure - if you were to copy all the code in top2 into main, the segfault wouldn't happen.

I know that this is definitely a GDC thing - the same code under DMD works correctly (i.e. prints the whole linked structure and doesn't segfault).

Reply via email to