Thread overview
How to create dynamically sized objects
Sep 29, 2016
Straivers
Sep 29, 2016
Straivers
Sep 30, 2016
Nicholas Wilson
September 29, 2016
Hi,

Say I wanted to create an object that has a string member, and I want the string to be allocated with the object contiguously instead of as a pointer to another location (as a constructor would do). For example:

class C {
    this(int i, string s) {
        this.i = i;
        this.s = s.toUTF16z();
    }

    int i;
    wstring s;
}

I want to allocate memory such that it looks like this:

[32-bit int][s.length * wchar.sizeof bytes]

I've considered using a separate function to create the class, but I don't know how setting the length of the string would behave. The only solution I can think of would be to have a constructor like this:

this(int i, string s, void[] mem) {
    emplace!int(mem.ptr, i);

    auto t = cast(dchar[]) mem[int.sizeof .. $];
    this.s.fill(s.byDChar())
}

Is there a better way to do this?
September 29, 2016
Actually, would just passing the parameters and an allocator do it? You'd just need to allocate the string in the constructor, right?
September 30, 2016
On Thursday, 29 September 2016 at 07:10:44 UTC, Straivers wrote:
> Hi,
>
> Say I wanted to create an object that has a string member, and I want the string to be allocated with the object contiguously instead of as a pointer to another location (as a constructor would do). For example:
>
> class C {
>     this(int i, string s) {
>         this.i = i;
>         this.s = s.toUTF16z();
>     }
>
>     int i;
>     wstring s;
> }
>
> I want to allocate memory such that it looks like this:
>
> [32-bit int][s.length * wchar.sizeof bytes]
>
> I've considered using a separate function to create the class, but I don't know how setting the length of the string would behave. The only solution I can think of would be to have a constructor like this:
>
> this(int i, string s, void[] mem) {
>     emplace!int(mem.ptr, i);
>
>     auto t = cast(dchar[]) mem[int.sizeof .. $];
>     this.s.fill(s.byDChar())
> }
>
> Is there a better way to do this?

struct Foo
{
    uint length;
    wchar[0] str; //this is the equivalent of wchar_t[] in C. i.e variable length.
}
auto newFoo(wstring s)
{
    auto fooMem = new ubyte[ unit.sizeof + wchar.sizeof*s.length];// you may need trailing '\0' if you are trying to interoperate with C.
    auto ret = cast(Foo*) fooMem;
    ret.length = s.length;
    memcpy(&ret.str,s.ptr, wchar.sizeof*s.length);
    return ret;
}