The code snippet from the book is:
// Allocate room for 10 MyClass objects
MyClass * buffer =
cast(MyClass*)GC.calloc(
__traits(classInstanceSize, MyClass) * 10);
class MyClass
{
int a;
string name;
char c;
}
MyClass is defined as a simple class, which requires padding after char c (intentionally).
I want to use GC.calloc to allocate memory for 10 MyClass instances.
But using __traits(classInstanceSize, MyClass) result in 41 bytes, which will require padding.
So I manually add extra bytes to allow each MyClass instance to have an address divisible by 8.
Then I want to initialize them with with core.lifetime.emplace() with default constructor.
Finally, use array index syntax to write to member variables. (This part breaks at run time)
Hopefully, this will be interesting.
Thank you for your assistance!
Console when run:
myClassActualSize: 41
myPaddedClassSize: 48
bytesNeeded: 480
myClasses address: 2864A4A1000
myClassPtrs[0]: 2864A4A1000
i: 0, buffer: 2864A4A1000
* The terminal process "C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -Command "& 'rdmd' 'c:\dev\D\81 - 90\c88_3c_GC_calloc_MyClass\source\app.d'"" terminated with exit code: 1.
source/app.d
import std.stdio;
import core.memory;
import core.lifetime;
void main()
{
// Allocate room for 10 MyClass objects
immutable size_t myClassActualSize = __traits(classInstanceSize, MyClass);
writeln("myClassActualSize: ", myClassActualSize);
// ensure myClassSize is divisible by 8, to allow for padding
immutable padding = 8;
immutable size_t myPaddedClassSize =
(myClassActualSize % padding == 0) ? myClassActualSize : (myClassActualSize + padding) / padding * padding;
writeln("myPaddedClassSize: ", myPaddedClassSize);
immutable bytesNeeded = myPaddedClassSize * 10;
writeln("bytesNeeded: ", bytesNeeded);
MyClass* myClasses = cast(MyClass *) GC.calloc(bytesNeeded);
writeln("myClasses address: ", myClasses);
alias MyClassPtr = MyClass *;
MyClassPtr[10] myClassPtrs;
foreach (i; 0 .. 9) {
myClassPtrs[i] = myClasses + i * myPaddedClassSize / padding;
writefln("myClassPtrs[%s]: %s ", i, myClassPtrs[i]);
auto buffer = cast(MyClass *) emplace(myClassPtrs[i]);
writefln("i: %s, buffer: %s", i, buffer);
writeln("i: %s, a: %s", i, myClassPtrs[i].a); // Compiles. Run time hangs/exception
}
}
class MyClass
{
int a;
string name;
char c;
}