Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
October 09, 2008 Array-initialization | ||||
---|---|---|---|---|
| ||||
Hi, i have a question regarding array-initialization. consider: struct STRUCT { byte[] data; } STRUCT foo(byte[] myData) { STRUCT* s = new STRUCT(myData); } do i now create a struct with an array on the heap and then drop the array and assign to the array-pointer the array "myData"? If yes, how can i avoid the creation and deletion of the array "data" in the first place? Am i right, that the variable "data" only holds a pointer to the real array? regards, hendrik |
October 09, 2008 Re: Array-initialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hendrik Renken | Hendrik Renken wrote:
> Hi,
>
> i have a question regarding array-initialization.
>
>
> consider:
>
> struct STRUCT
> {
> byte[] data;
> }
>
>
> STRUCT foo(byte[] myData)
> {
> STRUCT* s = new STRUCT(myData);
> }
>
>
> do i now create a struct with an array on the heap and then drop the array and assign to the array-pointer the array "myData"? If yes, how can i avoid the creation and deletion of the array "data" in the first place? Am i right, that the variable "data" only holds a pointer to the real array?
"data" is a dynamic array reference, so STRUCT is really just this:
struct STRUCT
{
size_t length;
byte* ptr;
}
So "data" is just a number of elements and a pointer to the first one. When you do "new STRUCT(myData)", you're only allocating room for that. There's no room for array contents allocated, just the reference.
If you do writeln(STRUCT.sizeof); it will always say 8 on a 32-bit system, same goes for data.sizeof.
Your example should probably look like this, as there's no point in heap allocating small structs:
STRUCT foo(byte[] myData)
{
STRUCT s = STRUCT(myData);
}
|
October 10, 2008 Re: Array-initialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | > "data" is a dynamic array reference, so STRUCT is really just this: > > struct STRUCT > { > size_t length; > byte* ptr; > } This explains everything. Thanks. > So "data" is just a number of elements and a pointer to the first one. > When you do "new STRUCT(myData)", you're only allocating room for that. There's no room for array contents allocated, just the reference. > > If you do writeln(STRUCT.sizeof); it will always say 8 on a 32-bit system, same goes for data.sizeof. > > let me modify your example: > STRUCT foo(byte[] myData) > { > STRUCT s = STRUCT(myData); return s; > } will the content of s now be copied when it is returned? > > Your example should probably look like this, as there's no point in heap > allocating small structs: > what means small? below how many bytes? |
October 10, 2008 Re: Array-initialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hendrik Renken | On Fri, Oct 10, 2008 at 4:42 AM, Hendrik Renken <funsheep@gmx.net> wrote: > let me modify your example: > >> STRUCT foo(byte[] myData) >> { >> STRUCT s = STRUCT(myData); > > return s; >> >> } > > > will the content of s now be copied when it is returned? Yes, the contents of *s* will be copied (that is, the array reference), but *not* the array data itself. >> Your example should probably look like this, as there's no point in heap allocating small structs: >> > > what means small? below how many bytes? It's subjective, but a struct that's only 4-8 bytes can be easily passed around in registers and there is therefore no need to heap-allocate it. Of course on a 64-bit platform even a 16-byte struct is small. |
October 10, 2008 Re: Array-initialization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hendrik Renken | "Hendrik Renken" wrote > >> "data" is a dynamic array reference, so STRUCT is really just this: >> >> struct STRUCT >> { >> size_t length; >> byte* ptr; >> } > > > This explains everything. Thanks. > > >> So "data" is just a number of elements and a pointer to the first one. >> When you do "new STRUCT(myData)", you're only allocating room for that. >> There's no room for array contents allocated, just the reference. >> >> If you do writeln(STRUCT.sizeof); it will always say 8 on a 32-bit system, same goes for data.sizeof. >> >> > > > let me modify your example: > >> STRUCT foo(byte[] myData) >> { >> STRUCT s = STRUCT(myData); > return s; >> } > > > will the content of s now be copied when it is returned? the pointer will be copied. If you want a copy of the data, try this: STRUCT s = STRUCT(myData.dup); This duplicates the data before setting the pointer. array.dup is a shallow copy, so if you are duping an array of pointers, only the pointers get copied, not the data they point to. If you want a 'deep' copy, you have to loop and do it yourself at this point. > > > > > > Your example should probably look like this, as there's no point in heap allocating small structs: > > > > what means small? below how many bytes? All heap allocations are a minimum of 16 bytes. So if you are allocating a struct that just contains a pointer and a length (i.e. an array), that is an 8-byte struct on a 32 bit system. That means 100% overhead... Plus heap allocations require grabbing a global thread mutex, finding a suitable allocation block, possibly running a garbage collect cycle. They are slow, much slower than using a stack allocated struct. Of course if you are copying the data, a dup is going to do a heap allocation, so not much is gained by putting your struct on the stack. However, you probably don't *need* to use the heap for the struct data, I'd recommend against it. -Steve |
Copyright © 1999-2021 by the D Language Foundation