Segfault with std.container.Array but not regular dynamic array

Joseph Rushton Wakeling joseph.wakeling at webdrake.net
Mon Nov 26 07:44:36 PST 2012


Hello all,

I'm writing some code which is meant to represent a network of linked nodes.

Each node is represented by a struct that contains the node's ID and an array of
links to other nodes.  Just as an experiment, I've tried out two different ways
of doing this:

////////////////////////////////////////////////////////////////
struct Node1
{
	uint id;
	Link[] links;

	this(uint id)
	{
		this.id = id;
	}

	void addLink(uint l)
	{
		links ~= Link(l);
	}
}

struct Node2
{
	uint id;
	Array!(Link) links;

	this(uint id)
	{
		this.id = id;
	}

	void addLink(uint l)
	{
		links.insert(Link(l));
	}
}
////////////////////////////////////////////////////////////////

Now, either of these seem to work fine per se.  Just as a simple test, you can
do something like,

	auto n1 = Node1(1);
	auto n2 = Node2(2);

	n1.addLink(5);
	n1.addLink(6);
	writeln(n1.links[0].id, "\t", n1.links[1].id);

	n2.addLink(7);
	n2.addLink(8);
	writeln(n2.links[0].id, "\t", n2.links[1].id);

... and all the correct results come out as you'd expect.

Now, suppose I want to implement a struct that groups together these nodes.
Here's a go:

////////////////////////////////////////////////////////////////
struct Network(Node)
{
	Node[uint] nodes;

	void add(uint i, uint j)
	{
		if((i in nodes) is null)
			nodes[i] = Node(i);
		if((j in nodes) is null)
			nodes[j] = Node(j);

		nodes[i].addLink(j);
		nodes[j].addLink(i);
	}

	void print()
	{
		foreach(k; nodes.keys)
		{
			write("[", k, "]");
			foreach(l; nodes[k].links)
				write(" ", l.id);
			writeln();
		}
		writeln();
	}
}
////////////////////////////////////////////////////////////////

However, while this structure (which is essentially a wrapper around an
associative array between node IDs and actual nodes) works fine with Node1, the
dynamic array-based node structure, it fails with Node2, which is based on
std.container.Array.

e.g. this works:

	Network!Node1 net1;
	net1.add(1, 5);
	net1.print();
	net1.add(1, 6);
	net1.print();

... but this segfaults:

	Network!Node2 net2;
	net2.add(1, 7);

I'm a bit confused as to why.  By the look of things it's actually the creation
of new entries in the Node[uint] associative array, rather than appending links
to the individual nodes.  Can anyone advise?

On a slightly different note, where std.container.Array is concerned: how come I 
can't use a foreach(i, x; myArray) formulation?  I.e. one where the foreach can 
infer the index value as well as the contained value ...

Thanks & best wishes,

     -- Joe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nodes.d
Type: text/x-dsrc
Size: 1110 bytes
Desc: not available
URL: <http://lists.puremagic.com/pipermail/digitalmars-d-learn/attachments/20121126/204d5855/attachment-0001.d>


More information about the Digitalmars-d-learn mailing list