www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Initialize class at given location

reply tzsz <writing.segfaults gmail.com> writes:
Hello,
I'd like to ask if there is any way of creating a class instance 
at a location given by a pointer.
In C++ this is usually done using new(pointer) MyClass(); and I 
saw a post made by Walter Bright that suggested adding this to D. 
The code from that post did not compile on my machine tho. And 
the post was a few years old, so I don't know what the current 
state regarding this feature is. I really tried finding something 
via Google but I was unsuccessful.

The reason for this is that I am looking for a way to use classes 
with all their nice features but without the GC. Therefore I'd be 
doing all the (de)allocations on my own. For this, I am currently 
using malloc and free from core.stdc.

Kind regards
Nov 28
next sibling parent reply drug007 <drug2004 bk.ru> writes:
On 28.11.2025 21:14, tzsz wrote:
 Hello,
 I'd like to ask if there is any way of creating a class instance at a 
 location given by a pointer.
 In C++ this is usually done using new(pointer) MyClass(); and I saw a 
 post made by Walter Bright that suggested adding this to D. The code 
 from that post did not compile on my machine tho. And the post was a few 
 years old, so I don't know what the current state regarding this feature 
 is. I really tried finding something via Google but I was unsuccessful.
 
 The reason for this is that I am looking for a way to use classes with 
 all their nice features but without the GC. Therefore I'd be doing all 
 the (de)allocations on my own. For this, I am currently using malloc and 
 free from core.stdc.
 
 Kind regards
In C++ it is called placement new. In D you should emplace class: ```D import core.lifetime : emplace; import core.stdc.stdlib : malloc, free; import std.stdio : writeln; class MyClass { int value; this(int v) { value = v; writeln("MyClass constructor called with value: ", value); } ~this() { writeln("MyClass destructor called for value: ", value); } } void main() { // Allocate memory for MyClass void* rawMemory = malloc(__traits(classInstanceSize, MyClass)); if (!rawMemory) { throw new Exception("Out of memory!"); } // Cast the raw memory to the class type MyClass instancePtr = cast(MyClass)rawMemory; // Emplace the MyClass instance emplace!MyClass(instancePtr, 10); // Now you can use instancePtr as a regular class instance writeln("Value from emplaced instance: ", instancePtr.value); // Remember to manually call the destructor and free the memory for non-GC allocated objects destroy(instancePtr); free(rawMemory); } ```
Nov 28
next sibling parent reply Brother Bill <brotherbill mail.com> writes:
On Friday, 28 November 2025 at 18:42:44 UTC, drug007 wrote:
 On 28.11.2025 21:14, tzsz wrote:
 In C++ it is called placement new. In D you should emplace 
 class:
This is quite helpful. Could you provide another toy example where we have abstract Vehicle class, then effective Car class derived from Vehicle, then Toyota class derived from Car class. The Toyota class needs to call Car constructor, which may need to call Vehicle constructor, then complete its own constructor. Vehicle class has member of int speed (in Miles per hour), which will be used in the example. All classes have explicit constructors and explicit destructors. This example would complete the understanding of using emplace for me. Working examples that can be reproduced are the best teachers. It is my understanding that using emplace as shown will make this class pointer outside the scope of the GC. Avoiding GC seems to be popular with Zig, Rust and other languages. It seems that D can play this game too.
Nov 28
next sibling parent drug007 <drug2004 bk.ru> writes:
On 28.11.2025 22:32, Brother Bill wrote:
 On Friday, 28 November 2025 at 18:42:44 UTC, drug007 wrote:
 On 28.11.2025 21:14, tzsz wrote:
 In C++ it is called placement new. In D you should emplace class:
This is quite helpful.  Could you provide another toy example where we have abstract Vehicle class, then effective Car class derived from Vehicle, then Toyota class derived from Car class. The Toyota class needs to call Car constructor, which may need to call Vehicle constructor, then complete its own constructor. Vehicle class has member of int speed (in Miles per hour), which will be used in the example.  All classes have explicit constructors and explicit destructors. This example would complete the understanding of using emplace for me. Working examples that can be reproduced are the best teachers. It is my understanding that using emplace as shown will make this class pointer outside the scope of the GC. Avoiding GC seems to be popular with Zig, Rust and other languages. It seems that D can play this game too.
It might look like this: ```D import core.lifetime : emplace; import std.stdio : writeln, writefln; import std.experimental.allocator.mallocator : Mallocator; abstract class Vehicle { protected int speed; this(int initialSpeed) { this.speed = initialSpeed; writeln("Vehicle constructor called, speed: ", this.speed, " MPH."); } abstract void drive(); ~this() { writeln("Vehicle destructor called."); } } class Car : Vehicle { protected int wheels; this(int speed, int wheels) { super(speed); // Call Vehicle constructor this.wheels = wheels; writeln("Car constructor called, wheels: ", this.wheels); } override void drive() { writeln("A car is driving at ", speed, " MPH on ", wheels, " wheels."); } ~this() { writeln("Car destructor called."); } } class Toyota : Car { protected string model; this(int speed, string model) { super(speed, 4); // Call Car constructor (which calls Vehicle's) this.model = model; writeln("Toyota constructor called, model: ", this.model); } // Toyota can use the drive method inherited from Car/Vehicle ~this() { writeln("Toyota destructor called."); } } void main() { // Determine size needed for the concrete type we are emplacing (Toyota) enum size = __traits(classInstanceSize, Toyota); writeln("Size needed for Toyota instance: ", size, " bytes."); // Manually allocate memory using allocator, not C heap void[] rawMemory = Mallocator.instance.allocate(size); if (!rawMemory.ptr) throw new Exception("Out of memory!"); writefln("Allocated raw memory address: %s, size: %s", rawMemory.ptr, rawMemory.length); // Using the slice above you can print the content of your instance writeln("\nUninitialized memory before Toyota instance construction"); writefln("%(%02x %)\n", rawMemory); // Emplace the Toyota instance into the raw memory, calling its constructor // The constructors are called in order: Vehicle -> Car -> Toyota writeln("\n--- Emplacing the instance ---"); auto myToyota = emplace!Toyota(cast(Toyota)rawMemory.ptr, 60, "Corolla"); writeln("\nInitialized memory after Toyota instance construction"); writefln("%(%02x %)\n", rawMemory); // it is offtopic but first 8 bytes are pointer to vtable, // next 8 bytes are so called monitor, so speed from Vehicle // is next 4 bytes and wheels amount is next 4 bytes, // next 8 bytes are length of the model name and // the last 8 bytes are the pointer to the model name // Use the instance writeln("\n--- Using the instance ---"); myToyota.drive(); myToyota.speed = 65; // Can modify inherited members myToyota.drive(); writeln("\nInitialized memory after changing Toyota speed from 60 to 65"); writefln("%(%02x %)\n", rawMemory); // Manually destroy the object before freeing the memory writeln("\n--- Destroying the instance and freeing memory ---"); // The destructors are called in reverse order: Toyota -> Car -> Vehicle destroy(myToyota); // Free the manually allocated raw memory Mallocator.instance.deallocate(rawMemory); writeln("Memory freed."); } ```
Nov 28
prev sibling parent =?UTF-8?Q?Ali_=C3=87ehreli?= <acehreli yahoo.com> writes:
On 11/28/25 11:32 AM, Brother Bill wrote:

 Could you provide another toy example where we
 have abstract Vehicle class, then effective Car class derived from
 Vehicle, then Toyota class derived from Car class.
It's not the easiest read but I have the following information on emplace: https://ddili.org/ders/d.en/memory.html#ix_memory.construction,%20emplace Ali
Nov 28
prev sibling parent tzsz <writing.segfaults gmail.com> writes:
On Friday, 28 November 2025 at 18:42:44 UTC, drug007 wrote:
 On 28.11.2025 21:14, tzsz wrote:
 [...]
In C++ it is called placement new. In D you should emplace class: [...]
This looks perfect. Thank you ^^
Nov 28
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On Friday, 28 November 2025 at 18:14:15 UTC, tzsz wrote:
 Hello,
 I'd like to ask if there is any way of creating a class 
 instance at a location given by a pointer.
 In C++ this is usually done using new(pointer) MyClass(); and I 
 saw a post made by Walter Bright that suggested adding this to 
 D. The code from that post did not compile on my machine tho.
This is a newly added improvement, and only in the most recent compiler ```d struct S { int x; } void foo() { ubyte[S.sizeof] arr; auto s = new(arr) S(1); assert(arr == [1, 0, 0, 0]); } ``` builds with 2.111.0. But it doesn't work (assert fails). Apparently there was a bug here. dmd-nightly does work. See the [changelog entry](https://dlang.org/changelog/2.111.0.html#dmd.placementNew). -Steve
Nov 28