digitalmars.D.learn - How to implement this?
- Elvis Zhou (15/15) Apr 07 2022 struct A {}
- Era Scarecrow (2/7) Apr 07 2022 Maybe it should be `cast(A*) \&b.a`?
- Era Scarecrow (27/28) Apr 07 2022 Confusing HTML entities bit on here. Probably just ignore it.
- =?UTF-8?Q?Ali_=c3=87ehreli?= (68/77) Apr 07 2022 If that really is the case, you want to place the objects on memory that...
- Elvis Zhou (8/23) Apr 07 2022 I know where the issue comes from, dynamic array is GCed and save
- Elvis Zhou (5/14) Apr 07 2022 like,
- Stanislav Blinov (18/21) Apr 08 2022 That's what `@trusted` is for. And that's also why it should be
- Elvis Zhou (9/31) Apr 08 2022 Thank you, this is exactly what I'm looking for!
struct A {} struct B { A a; } struct C { A a; } A*[] structs; B b; init(&b); structs ~= cast(A*)&b; //Error: copying `cast(A*)& b` into allocated memory escapes a reference to local variable `b` C c; init(&c); structs ~= cast(A*)&c; //Error: copying `cast(A*)& c` into allocated memory escapes a reference to local variable `c` batch_process(structs);
Apr 07 2022
On Friday, 8 April 2022 at 04:31:45 UTC, Elvis Zhou wrote:B b; init(\&b); structs ~= cast(A*)\&b; //Error: copying `cast(A*)\& b` into allocated memory escapes a reference to local variable `b`Maybe it should be `cast(A*) \&b.a`?
Apr 07 2022
On Friday, 8 April 2022 at 04:54:35 UTC, Era Scarecrow wrote:Maybe it should be `cast(A*) &b.a`?Confusing HTML entities bit on here. Probably just ignore it. Maybe you are doing it backwards. What if you had ```d struct B { A* a; } A[] arraylist; ``` then in the init append a new item to A's array list, before doing: ```d arraylist ~= A(); a = &arraylist[$-1]; ``` Alternately, add a static list and have the batch function access both lists? ```d struct B { static A[] list; int a_index=-1; } a_index=list.length; list ~= A(); ``` then reference the item by list[a_index] or something similar.
Apr 07 2022
On 4/7/22 21:31, Elvis Zhou wrote:struct A {} struct B { A a; } struct C { A a; } A*[] structs; B b; init(&b); structs ~= cast(A*)&b; //Error: copying `cast(A*)& b` into allocated memory escapes a reference to local variable `b`If that really is the case, you want to place the objects on memory that will not go away. Dynamic arrays provide "memory" that is owned by the GC. The following program emplaces alternating Bs and Cs into a buffer and then batch_process'es them: struct A { int i; } struct B { A a; } struct C { A a; } A*[] structs; void append(T, Args...)(ref ubyte[] structs, Args args) { import std.conv : emplace; structs.length += sizeWithPadding!T; auto where = cast(T*)(&structs[$ - sizeWithPadding!T]); emplace(where, args); } void main() { ubyte[] structs; foreach (i; 0 .. 10) { if (i % 2) { structs.append!B(A(i)); } else { structs.append!C(A(i)); } } batch_process(structs); } auto process(T)(const(ubyte)[] structs) { import std.stdio : writeln; writeln(*cast(T*)structs.ptr); return structs[sizeWithPadding!T..$]; } void batch_process(const(ubyte)[] structs) { import std.range : empty; for (size_t i = 0; !structs.empty; i++) { if (i % 2) { structs = structs.process!B(); } else { structs = structs.process!C(); } } } T * nextAlignedAddress(T)(T * candidateAddr) { import std.traits; static if (is (T == class)) { const alignment = classInstanceAlignment!T; } else { const alignment = T.alignof; } const result = (cast(size_t)candidateAddr + alignment - 1) / alignment * alignment; return cast(T*)result; } void * nextAlignedAddress(T)(void * candidateAddr) { return nextAlignedAddress(cast(T*)candidateAddr); } size_t sizeWithPadding(T)() { static if (is (T == class)) { const candidateAddr = __traits(classInstanceSize, T); } else { const candidateAddr = T.sizeof; } return cast(size_t)nextAlignedAddress(cast(T*)candidateAddr); } I copied nextAlignedAddress() and sizeWithPadding() functions from this chapter: http://ddili.org/ders/d.en/memory.html Everything I did in the program above is explained there. Ali
Apr 07 2022
On Friday, 8 April 2022 at 04:31:45 UTC, Elvis Zhou wrote:struct A {} struct B { A a; } struct C { A a; } A*[] structs; B b; init(&b); structs ~= cast(A*)&b; //Error: copying `cast(A*)& b` into allocated memory escapes a reference to local variable `b` C c; init(&c); structs ~= cast(A*)&c; //Error: copying `cast(A*)& c` into allocated memory escapes a reference to local variable `c` batch_process(structs);I know where the issue comes from, dynamic array is GCed and save the reference of a local variable in GCed memory is not allowed, but here structs is assumed to not escape, it can be simply achieved by using a fixed-size array instead, ie A*[32] structs; int i = 0; structs[i++] = cast(A*)&b; However I wonder if there be a stack allocated array with max capacity limits, which can be concated like with normal dynamic one.
Apr 07 2022
On Friday, 8 April 2022 at 05:46:56 UTC, Elvis Zhou wrote:On Friday, 8 April 2022 at 04:31:45 UTC, Elvis Zhou wrote:like, assumeNoEscapeOrWhatever!DynamicArray structs; structs ~= cast(A*)&b; is it possible?[...]I know where the issue comes from, dynamic array is GCed and save the reference of a local variable in GCed memory is not allowed, but here structs is assumed to not escape, it can be simply achieved by using a fixed-size array instead, ie A*[32] structs; int i = 0; structs[i++] = cast(A*)&b; However I wonder if there be a stack allocated array with max capacity limits, which can be concated like with normal dynamic one.
Apr 07 2022
On Friday, 8 April 2022 at 05:53:03 UTC, Elvis Zhou wrote:assumeNoEscapeOrWhatever!DynamicArray structs; structs ~= cast(A*)&b; is it possible?That's what ` trusted` is for. And that's also why it should be used with care, and on the smallest code possible. ```d struct A {} struct B { A a; } struct C { A a; } void main() { A*[] structs; B b; C c; () trusted { structs ~= cast(A*)&b; structs ~= cast(A*)&c; } (); } ```
Apr 08 2022
On Friday, 8 April 2022 at 09:08:07 UTC, Stanislav Blinov wrote:On Friday, 8 April 2022 at 05:53:03 UTC, Elvis Zhou wrote:Thank you, this is exactly what I'm looking for! But why this doesn't work? void func() trusted { A*[] structs; B b; structs ~= cast(A*)&b; // still error }assumeNoEscapeOrWhatever!DynamicArray structs; structs ~= cast(A*)&b; is it possible?That's what ` trusted` is for. And that's also why it should be used with care, and on the smallest code possible. ```d struct A {} struct B { A a; } struct C { A a; } void main() { A*[] structs; B b; C c; () trusted { structs ~= cast(A*)&b; structs ~= cast(A*)&c; } (); } ```
Apr 08 2022