www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Dynamic array void initialization

reply Tom <tom nospam.com> writes:
import std.stdio;

struct S {
	int i;
	int j;
}

int main(string[] args) {
	S[] ss = void;
	ss.length = 5;
	foreach (ref s; ss)
		s = S(1, 2);
	return 0;
}

Is the above code correct? (it doesn't work... it blows away or just 
give and access violation error).

I need to create a dynamic array of some struct, but don't want defer 
contained elements initialization (for performance reasons).

Tom;
Mar 08 2011
next sibling parent reply =?ISO-8859-1?Q?Ali_=C7ehreli?= <acehreli yahoo.com> writes:
On 03/08/2011 01:34 PM, Tom wrote:
 import std.stdio;

 struct S {
 int i;
 int j;
 }

 int main(string[] args) {
 S[] ss = void;
 ss.length = 5;
 foreach (ref s; ss)
 s = S(1, 2);
 return 0;
 }

 Is the above code correct? (it doesn't work... it blows away or just
 give and access violation error).

 I need to create a dynamic array of some struct, but don't want defer
 contained elements initialization (for performance reasons).

 Tom;

There is std.array.reserve: import std.array; struct S { int i; int j; } int main(string[] args) { S[] ss; reserve(ss, 5); // or if you want to confuse yourself (and me): ss.reserve(5); // same thing as above foreach (ref s; ss) s = S(1, 2); return 0; } Ali
Mar 08 2011
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 08 Mar 2011 16:53:08 -0500, Ali Çehreli <acehreli yahoo.com> wrote:

 On 03/08/2011 01:34 PM, Tom wrote:
 import std.stdio;

 struct S {
 int i;
 int j;
 }

 int main(string[] args) {
 S[] ss = void;
 ss.length = 5;
 foreach (ref s; ss)
 s = S(1, 2);
 return 0;
 }

 Is the above code correct? (it doesn't work... it blows away or just
 give and access violation error).

 I need to create a dynamic array of some struct, but don't want defer
 contained elements initialization (for performance reasons).

 Tom;

There is std.array.reserve: import std.array; struct S { int i; int j; } int main(string[] args) { S[] ss; reserve(ss, 5); // or if you want to confuse yourself (and me): ss.reserve(5); // same thing as above foreach (ref s; ss) s = S(1, 2); return 0; }

Some clarifications: it's not std.array.reserve, it's object.reserve, always present, no need to import. I believe if the type contains pointers the GC still writes 0s to the unused data to prevent false pointers. However, reserve on an int or a struct that just contains ints should not pre-initialize. reserve ensures appropriate space for appending, it does *not* alter the array's length. So your foreach loop would not execute (at that point, ss.length is still 0). To work properly, you would need to use the append operator. Bearophile has requested an ability to create a dynamic array uninitialized, and I think there is a bug report for that. Currently, there is no "easy way" to do it. -Steve
Mar 08 2011
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/08/2011 02:03 PM, Steven Schveighoffer wrote:

 it's not std.array.reserve, it's object.reserve, always present, no need
 to import.

Thanks. The reserve that I found in array.d is std.array.Appender(T).reserve. Ali
Mar 08 2011
prev sibling parent Tom <tom nospam.com> writes:
El 08/03/2011 19:03, Steven Schveighoffer escribió:
 On Tue, 08 Mar 2011 16:53:08 -0500, Ali Çehreli <acehreli yahoo.com> wrote:

 On 03/08/2011 01:34 PM, Tom wrote:
 import std.stdio;

 struct S {
 int i;
 int j;
 }

 int main(string[] args) {
 S[] ss = void;
 ss.length = 5;
 foreach (ref s; ss)
 s = S(1, 2);
 return 0;
 }

 Is the above code correct? (it doesn't work... it blows away or just
 give and access violation error).

 I need to create a dynamic array of some struct, but don't want defer
 contained elements initialization (for performance reasons).

 Tom;

There is std.array.reserve: import std.array; struct S { int i; int j; } int main(string[] args) { S[] ss; reserve(ss, 5); // or if you want to confuse yourself (and me): ss.reserve(5); // same thing as above foreach (ref s; ss) s = S(1, 2); return 0; }

Some clarifications: it's not std.array.reserve, it's object.reserve, always present, no need to import. I believe if the type contains pointers the GC still writes 0s to the unused data to prevent false pointers. However, reserve on an int or a struct that just contains ints should not pre-initialize. reserve ensures appropriate space for appending, it does *not* alter the array's length. So your foreach loop would not execute (at that point, ss.length is still 0). To work properly, you would need to use the append operator. Bearophile has requested an ability to create a dynamic array uninitialized, and I think there is a bug report for that. Currently, there is no "easy way" to do it. -Steve

http://d.puremagic.com/issues/show_bug.cgi?id=5603 This is really sad. This kind of stuff is a must for performance. D is disappointing me too much yet :(
Mar 08 2011
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 08 Mar 2011 17:48:37 -0500, Tom <tom nospam.com> wrote:

 http://d.puremagic.com/issues/show_bug.cgi?id=5603

 This is really sad. This kind of stuff is a must for performance. D is  
 disappointing me too much yet :(

There is always c's malloc, or you can try using the GC malloc directly. For application specific needs, it might be sufficient. However, a builtin language/library feature must be very robust and handle all cases. -Steve
Mar 08 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 03/08/2011 11:57 PM, Steven Schveighoffer wrote:
 On Tue, 08 Mar 2011 17:48:37 -0500, Tom <tom nospam.com> wrote:

 http://d.puremagic.com/issues/show_bug.cgi?id=5603

 This is really sad. This kind of stuff is a must for performance. D is
 disappointing me too much yet :(

There is always c's malloc, or you can try using the GC malloc directly. For application specific needs, it might be sufficient. However, a builtin language/library feature must be very robust and handle all cases.

I recently discovered the GC module refactored (with all funcs now integrated into the type): very good job; everything is now clear and easy to use. Denis -- _________________ vita es estrany spir.wikidot.com
Mar 08 2011
prev sibling parent reply Kai Meyer <kai unixlords.com> writes:
On 03/08/2011 02:34 PM, Tom wrote:
 import std.stdio;

 struct S {
 int i;
 int j;
 }

 int main(string[] args) {
 S[] ss = void;
 ss.length = 5;
 foreach (ref s; ss)
 s = S(1, 2);
 return 0;
 }

 Is the above code correct? (it doesn't work... it blows away or just
 give and access violation error).

 I need to create a dynamic array of some struct, but don't want defer
 contained elements initialization (for performance reasons).

 Tom;

Any reason you don't just do this: S[] ss; ss.reserve(5) foreach(i; 0..i) ss ~= S(1, 2); I think that would not do default initialization on any of the elements, and it would ensure that the dynamic array is own "grown" once.
Mar 08 2011
next sibling parent Kai Meyer <kai unixlords.com> writes:
On 03/08/2011 05:42 PM, Kai Meyer wrote:
 On 03/08/2011 02:34 PM, Tom wrote:
 import std.stdio;

 struct S {
 int i;
 int j;
 }

 int main(string[] args) {
 S[] ss = void;
 ss.length = 5;
 foreach (ref s; ss)
 s = S(1, 2);
 return 0;
 }

 Is the above code correct? (it doesn't work... it blows away or just
 give and access violation error).

 I need to create a dynamic array of some struct, but don't want defer
 contained elements initialization (for performance reasons).

 Tom;

Any reason you don't just do this: S[] ss; ss.reserve(5) foreach(i; 0..i) ss ~= S(1, 2); I think that would not do default initialization on any of the elements, and it would ensure that the dynamic array is own "grown" once.

Sorry, foreach(i; 0..5) That's what I get for writing code with out trying to run it....
Mar 08 2011
prev sibling parent Tom <tom nospam.com> writes:
El 08/03/2011 21:42, Kai Meyer escribi:
 On 03/08/2011 02:34 PM, Tom wrote:
 import std.stdio;

 struct S {
 int i;
 int j;
 }

 int main(string[] args) {
 S[] ss = void;
 ss.length = 5;
 foreach (ref s; ss)
 s = S(1, 2);
 return 0;
 }

 Is the above code correct? (it doesn't work... it blows away or just
 give and access violation error).

 I need to create a dynamic array of some struct, but don't want defer
 contained elements initialization (for performance reasons).

 Tom;

Any reason you don't just do this: S[] ss; ss.reserve(5) foreach(i; 0..i) ss ~= S(1, 2); I think that would not do default initialization on any of the elements, and it would ensure that the dynamic array is own "grown" once.

Nope, you're right. That'll work for me. Thank you, Tom;
Mar 08 2011