Jump to page: 1 2
Thread overview
dynamic array of structs?
Nov 29, 2004
alexander.panek
Nov 29, 2004
Chris Sauls
Nov 29, 2004
Stewart Gordon
Nov 29, 2004
Chris Sauls
Nov 29, 2004
Ben Hinkle
Nov 29, 2004
alexander.panek
Nov 29, 2004
Regan Heath
Nov 29, 2004
alexander.panek
Nov 29, 2004
Dave
Nov 29, 2004
Russ Lewis
Nov 29, 2004
alexander.panek
Nov 29, 2004
Sjoerd van Leent
Nov 29, 2004
Derek Parnell
Nov 30, 2004
Russ Lewis
Nov 30, 2004
Derek Parnell
Nov 30, 2004
Russ Lewis
Nov 30, 2004
Stewart Gordon
Nov 30, 2004
Simon Buchan
November 29, 2004
Hello,

I got a problem with an array of structs in a class: when I declare the array inside the class as static, everything works fine. But as soon as I try to handle that with a dynamical array it tells me "Error: ArrayBoundsError <file(line)>". Is there no way to use dynamic arrays of structs? or did I just misused that?

struct foo {
char[] x;
}

class bar {
private foo [] y;

this() { foo[0].x = "hello world"; } // <--- there i get the error
}

The only problem is, I didn`t find any simular examples in the documentation (only structs and dynamical standard-type-arrays).

Hope you can help me.

Thanks, Alex


November 29, 2004
In article <cofnsm$1510$1@digitaldaemon.com>, alexander.panek@brainsware.org says...
>
>Hello,
>
>I got a problem with an array of structs in a class: when I declare the array inside the class as static, everything works fine. But as soon as I try to handle that with a dynamical array it tells me "Error: ArrayBoundsError <file(line)>". Is there no way to use dynamic arrays of structs? or did I just misused that?
>
>struct foo {
>char[] x;
>}
>
>class bar {
>private foo [] y;
>
>this() { foo[0].x = "hello world"; } // <--- there i get the error
>}
>

The problem here is a simple but common one.  You are attempting to access the first value in a set with /zero/ items.  Here are a couple of correct examples:

this() {
foo ~= "hello world";
}


this() {
foo.length = 1;
foo[0] = "hello world";
}

Even dynamic arrays have to be told their length before using them.  I'm fond of the first method (concatenation) myself, but there are times when the second method is best.  Experimentation will pay off here.

-- Chris Sauls


November 29, 2004
In article <cofq5q$18dv$1@digitaldaemon.com>, Chris Sauls says... <snip>
> The problem here is a simple but common one.  You are attempting to access the first value in a set with /zero/ items.  Here are a couple of correct examples:
> 
> this() {
> foo ~= "hello world";
> }
<snip>

Read the OP's code again.  foo is a data type.  How can you append something to a data type?

Stewart.


November 29, 2004
In article <cofr30$19v7$1@digitaldaemon.com>, Stewart Gordon says...
>
>In article <cofq5q$18dv$1@digitaldaemon.com>, Chris Sauls says... <snip>
>> The problem here is a simple but common one.  You are attempting to access the first value in a set with /zero/ items.  Here are a couple of correct examples:
>> 
>> this() {
>> foo ~= "hello world";
>> }
><snip>
>
>Read the OP's code again.  foo is a data type.  How can you append something to a data type?
>

Miff... you can tell I've been missing sleep, neh?  Change all the 'foo's to 'y's and all will be well.

-- Chris Sauls


November 29, 2004
In article <cofq5q$18dv$1@digitaldaemon.com>, Chris Sauls says...
>
>In article <cofnsm$1510$1@digitaldaemon.com>, alexander.panek@brainsware.org says...
>>
>>Hello,
>>
>>I got a problem with an array of structs in a class: when I declare the array inside the class as static, everything works fine. But as soon as I try to handle that with a dynamical array it tells me "Error: ArrayBoundsError <file(line)>". Is there no way to use dynamic arrays of structs? or did I just misused that?
>>
>>struct foo {
>>char[] x;
>>}
>>
>>class bar {
>>private foo [] y;
>>
>>this() { foo[0].x = "hello world"; } // <--- there i get the error
>>}
>>
>
>The problem here is a simple but common one.  You are attempting to access the first value in a set with /zero/ items.  Here are a couple of correct examples:
>
>this() {
>foo ~= "hello world";
>}
>
>
>this() {
>foo.length = 1;
>foo[0] = "hello world";
>}
>
>Even dynamic arrays have to be told their length before using them.  I'm fond of the first method (concatenation) myself, but there are times when the second method is best.  Experimentation will pay off here.
>
>-- Chris Sauls
>
>

Well. I tried those and neither the '~='-operater helped, nor is the length-property available for an array of structs. Shall I use an array of pointers instead of dynamic arrays or just a pointer for that? Maybe that helps..gonna try.

And before I forget:

<code>
>>struct foo {
>>char[] x;
>>}
>>
>>class bar {
>>private foo [] y;
>>
>>this() { y[0].x = "hello world"; } // <--- there i get the error
>>}
</code>

better? :P

Thanks, Alex


November 29, 2004
"Chris Sauls" <Chris_member@pathlink.com> wrote in message news:cofsei$1bvn$1@digitaldaemon.com...
> In article <cofr30$19v7$1@digitaldaemon.com>, Stewart Gordon says...
> >
> >In article <cofq5q$18dv$1@digitaldaemon.com>, Chris Sauls says... <snip>
> >> The problem here is a simple but common one.  You are attempting to access the first value in a set with /zero/ items.  Here are a couple of correct examples:
> >>
> >> this() {
> >> foo ~= "hello world";
> >> }
> ><snip>
> >
> >Read the OP's code again.  foo is a data type.  How can you append something to a data type?
> >
>
> Miff... you can tell I've been missing sleep, neh?  Change all the 'foo's
to
> 'y's and all will be well.
>
> -- Chris Sauls
>
>

the OP used foo[0].x as well so you aren't alone.


November 29, 2004
alexander.panek@brainsware.org wrote:
> Hello,
> 
> I got a problem with an array of structs in a class: when I declare the array
> inside the class as static, everything works fine. But as soon as I try to
> handle that with a dynamical array it tells me "Error: ArrayBoundsError
> <file(line)>". Is there no way to use dynamic arrays of structs? or did I just
> misused that?
> 
> struct foo {
> char[] x;
> }
> 
> class bar {
> private foo [] y;
> 
> this() { foo[0].x = "hello world"; } // <--- there i get the error
> }
> 
> The only problem is, I didn`t find any simular examples in the documentation
> (only structs and dynamical standard-type-arrays).

The issue has nothing to do with structs, it turns out.  The same problem would be true with classes.

First, you have a syntax error.  In the last line, you attempt to access
	foo[0]
but foo is a type.  So this is obviously wrong.  You can't use a type like it was an array variable.  So I'm going to assume that you meant to do this:
	this() { y[0].x = "hello world"; }



The problem is, indeed, that you are accessing an invalid element of an array.  In this code, the array 'y' has 0 elements.  So you can't access any element of it until you put some elements in it.  Probably the easiest way to do it is:
	this() {
		y.length = 1;
		y[0].x = "hello world";
	}
Otherwise, you'll get an ArrayBoundsError the moment that you try to access
	y[0]

Now, why does it work when you make x static?  That's because, when you have a static variable, it can be accessed through any instance of the struct.  The instance doesn't have to be valid; the compiler only needs to know the type, and the rest of it is removed at compile time.  So, consider this code:
	struct fred {
		static char[] x;
	}
	struct wilma {
		private fred[] y;

		this() { y[0].x = "hello world"; }
	}
The last line of that code is totally the same as this code:
	this() { fred.x = "hello world"; }
So, since the compiler doesn't actually attempt to access y[0] in the static case, you don't get the ArrayBoundsError.



This is very similar to the code that is often used to find the offset of a member variable in a struct:
	struct X { int a; int b; }
	int offset_of_b = &((cast(X*)0).b);
In the above, you have a pointer variable which points to 0 (i.e. null).  It's obviously invalid to try to access the 'b' member of that struct.  But, since we only take the *address* of 'b' and we don't actually try to read it, we are ok.  The compiler actually should simplify it down to a constant value, so the line becomes something like:
	int offset_of_b = 4;

(Of course, I think D provides a property which allows us to get this more easily...but I can't remember exactly what it is.)

November 29, 2004
On Mon, 29 Nov 2004 19:45:07 +0000 (UTC), <alexander.panek@brainsware.org> wrote:
> In article <cofq5q$18dv$1@digitaldaemon.com>, Chris Sauls says...
>>
>> In article <cofnsm$1510$1@digitaldaemon.com>, alexander.panek@brainsware.org
>> says...
>>>
>>> Hello,
>>>
>>> I got a problem with an array of structs in a class: when I declare the array
>>> inside the class as static, everything works fine. But as soon as I try to
>>> handle that with a dynamical array it tells me "Error: ArrayBoundsError
>>> <file(line)>". Is there no way to use dynamic arrays of structs? or did I just
>>> misused that?
>>>
>>> struct foo {
>>> char[] x;
>>> }
>>>
>>> class bar {
>>> private foo [] y;
>>>
>>> this() { foo[0].x = "hello world"; } // <--- there i get the error
>>> }
>>>
>>
>> The problem here is a simple but common one.  You are attempting to access the
>> first value in a set with /zero/ items.  Here are a couple of correct examples:
>>
>> this() {
>> foo ~= "hello world";
>> }
>>
>>
>> this() {
>> foo.length = 1;
>> foo[0] = "hello world";
>> }
>>
>> Even dynamic arrays have to be told their length before using them.  I'm fond of
>> the first method (concatenation) myself, but there are times when the second
>> method is best.  Experimentation will pay off here.
>>
>> -- Chris Sauls
>>
>>
>
> Well. I tried those and neither the '~='-operater helped, nor is the
> length-property available for an array of structs. Shall I use an array of
> pointers instead of dynamic arrays or just a pointer for that? Maybe that
> helps..gonna try.
>
> And before I forget:
>
> <code>
>>> struct foo {
>>> char[] x;
>>> }
>>>
>>> class bar {
>>> private foo [] y;
>>>
>>> this() { y[0].x = "hello world"; } // <--- there i get the error
>>> }
> </code>
>
> better? :P

Both 'x' and 'y' are dynamic arrays.
Both require you to explicitly extend the length of them, or, use the append operator '~'.

Example:

import std.stdio;

struct foo {
  char[] x;
}

version(EXTEND) {
	class bar {
	  private foo[] y;
	  this() {
		foo f;
		writef("EXTEND\n");		
		f.x = "hello world";
		y ~= f;
	  }
	}
}
else {
	class bar {
	  private foo[] y;
	  this() {
	    foo f;
	    writef("APPEND\n");
	    f.x = "hello world";
	    y.length = y.length + 1;
	    y[y.length-1] = f;
	  }
	}
}

void main()
{
  bar b = new bar();
  writef(b.y[0].x,"\n");
}

compile with:
  "dmd dynamic.d" for the append version
  "dmd dynamic.d -version=EXTEND" for the extend version

Also note that:
  y[y.length-1] = f;

copies the 'f' foo structure into the array, which isn't a problem unless the struct is large in which case it is slower than using a class (which is a reference type thus all you copy is the reference to the class, not the actual class itself).

If you want speed and to use a struct then consider a struct pointer i.e.

struct foo {
  char[] x;
}

class bar {
  private foo*[] y;
  this() {
    foo *f = new foo();
    f.x = "hello world";
    y ~= f;
  }
}

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
November 29, 2004
In article <cog3t3$1mhg$1@digitaldaemon.com>, Russ Lewis says...
>
>alexander.panek@brainsware.org wrote:
>> Hello,
>> 
>> I got a problem with an array of structs in a class: when I declare the array inside the class as static, everything works fine. But as soon as I try to handle that with a dynamical array it tells me "Error: ArrayBoundsError <file(line)>". Is there no way to use dynamic arrays of structs? or did I just misused that?
>> 
>> struct foo {
>> char[] x;
>> }
>> 
>> class bar {
>> private foo [] y;
>> 
>> this() { foo[0].x = "hello world"; } // <--- there i get the error
>> }
>> 
>> The only problem is, I didn`t find any simular examples in the documentation (only structs and dynamical standard-type-arrays).
>
>The issue has nothing to do with structs, it turns out.  The same problem would be true with classes.
>
>First, you have a syntax error.  In the last line, you attempt to access
>	foo[0]
>but foo is a type.  So this is obviously wrong.  You can't use a type
>like it was an array variable.  So I'm going to assume that you meant to
>do this:
>	this() { y[0].x = "hello world"; }
>
>
>
>The problem is, indeed, that you are accessing an invalid element of an
>array.  In this code, the array 'y' has 0 elements.  So you can't access
>any element of it until you put some elements in it.  Probably the
>easiest way to do it is:
>	this() {
>		y.length = 1;
>		y[0].x = "hello world";
>	}
>Otherwise, you'll get an ArrayBoundsError the moment that you try to access
>	y[0]
>
>Now, why does it work when you make x static?  That's because, when you
>have a static variable, it can be accessed through any instance of the
>struct.  The instance doesn't have to be valid; the compiler only needs
>to know the type, and the rest of it is removed at compile time.  So,
>consider this code:
>	struct fred {
>		static char[] x;
>	}
>	struct wilma {
>		private fred[] y;
>
>		this() { y[0].x = "hello world"; }
>	}
>The last line of that code is totally the same as this code:
>	this() { fred.x = "hello world"; }
>So, since the compiler doesn't actually attempt to access y[0] in the
>static case, you don't get the ArrayBoundsError.
>
>
>
>This is very similar to the code that is often used to find the offset
>of a member variable in a struct:
>	struct X { int a; int b; }
>	int offset_of_b = &((cast(X*)0).b);
>In the above, you have a pointer variable which points to 0 (i.e. null).
>  It's obviously invalid to try to access the 'b' member of that struct.
>  But, since we only take the *address* of 'b' and we don't actually try
>to read it, we are ok.  The compiler actually should simplify it down to
>a constant value, so the line becomes something like:
>	int offset_of_b = 4;
>
>(Of course, I think D provides a property which allows us to get this more easily...but I can't remember exactly what it is.)
>

First of all: foo[0]... was a typing error. I meant y[0].

The problem will be, that I don`t only have to access one array-member. I want to save an XML-Attribute into this struct (name, value) - so I have to fill this dynamically (used for parsing and such things).

I don`t remember a better way to do something like that, as to use a struct to combine the data and not just writing it into the class as seperate variables.

Alex


November 29, 2004
alexander.panek@brainsware.org wrote:

> 
> First of all: foo[0]... was a typing error. I meant y[0].
> 
> The problem will be, that I don`t only have to access one array-member. I want
> to save an XML-Attribute into this struct (name, value) - so I have to fill this
> dynamically (used for parsing and such things).
> 
> I don`t remember a better way to do something like that, as to use a struct to
> combine the data and not just writing it into the class as seperate variables.
> 
> Alex
> 
> 


There is.

Use a associative array (or map). They are always fully dynamic. Example:

struct SomeStruct {
	char[] s;
}

int main(char[][] args) {
	SomeStruct[int] structs;

	SomeStruct s1;
	s1.s = "String 1";
	structs[0] = s1;

	SomeStruct s2;
	s2.s = "String 2";
	structs[1] = s2;

	return 0;
}

Note that using 0 and 1 again causes it to be overwritten.

Regards,
Sjoerd
« First   ‹ Prev
1 2