www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to create dynamically sized objects

reply Straivers <straivers98 gmail.com> writes:
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?
Sep 29 2016
next sibling parent Straivers <straivers98 gmail.com> writes:
Actually, would just passing the parameters and an allocator do 
it? You'd just need to allocate the string in the constructor, 
right?
Sep 29 2016
prev sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
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; }
Sep 29 2016