Debug help - Programming in D, page 670 allocate buffer of 10 MyClass class instances
Brother Bill
brotherbill at mail.com
Wed Sep 3 12:10:17 UTC 2025
On Wednesday, 3 September 2025 at 03:09:45 UTC, Ali Çehreli wrote:
> GC.calloc(bytesNeeded);
>
> Again, I misled you there.
>
> > writeln("myClasses address: ", myClasses);
> >
> > alias MyClassPtr = MyClass *;
>
> That's not useful because the type MyClass is already a
> reference type, implemented as a pointer by the compiler.
>
> Yes, pointer to a class type will make sense in some cases but
> not here.
>
> > MyClassPtr[10] myClassPtrs;
>
> So, that could be MyClass[]. Note, not the objects but MyClass
> values will be stored there, which are references to MyClass
> objects.
>
> > foreach (i; 0 .. 9) {
>
> I removed hard-coded 10 above because your loop was one less
> than 10 iterations.
>
> Ali
Made some further changes, and have additional questions.
Console output:
```
myClassActualSize: 41
myPaddedClassSize: 48
bytesNeeded: 480
myClasses address: 25DF6931000
0: {a: 0, name: Sally, c: D}, &myClasses[i]: 25DF6932000,
&myClasses[i].a: 25DF6931010
1: {a: 1, name: Sally, c: D}, &myClasses[i]: 25DF6932008,
&myClasses[i].a: 25DF6931040
2: {a: 2, name: Sally, c: D}, &myClasses[i]: 25DF6932010,
&myClasses[i].a: 25DF6931070
3: {a: 3, name: Sally, c: D}, &myClasses[i]: 25DF6932018,
&myClasses[i].a: 25DF69310A0
4: {a: 4, name: Sally, c: D}, &myClasses[i]: 25DF6932020,
&myClasses[i].a: 25DF69310D0
5: {a: 5, name: Sally, c: D}, &myClasses[i]: 25DF6932028,
&myClasses[i].a: 25DF6931100
6: {a: 6, name: Sally, c: D}, &myClasses[i]: 25DF6932030,
&myClasses[i].a: 25DF6931130
7: {a: 7, name: Sally, c: D}, &myClasses[i]: 25DF6932038,
&myClasses[i].a: 25DF6931160
8: {a: 8, name: Sally, c: D}, &myClasses[i]: 25DF6932040,
&myClasses[i].a: 25DF6931190
9: {a: 9, name: Sally, c: D}, &myClasses[i]: 25DF6932048,
&myClasses[i].a: 25DF69311C0
```
source/app.d
```
import std.stdio;
import std.string;
import core.memory;
import core.lifetime;
void main()
{
enum elementCount = 10;
// 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 * elementCount;
writeln("bytesNeeded: ", bytesNeeded);
void* myClassObjects = GC.calloc(bytesNeeded);
writeln("myClasses address: ", myClassObjects);
// [Ali] Note the type of the array:
// MyClass is a reference to object; no pointer needed
MyClass[] myClasses;
foreach (i; 0 .. elementCount) {
void * address = myClassObjects + (i * myPaddedClassSize);
// The first parameter guides emplace() of slice to
instantiate MyClass instance.
myClasses ~= emplace!MyClass(address[0 ..
myPaddedClassSize], i, "Sally", 'D');
}
writeln;
foreach (i; 0 .. elementCount) {
writefln("%s: %s, &myClasses[i]: %s, &myClasses[i].a: %s",
i, myClasses[i], &myClasses[i], &myClasses[i].a);
}
}
class MyClass
{
int a;
string name;
char c;
this(int a, string name, char c) {
this.a = a;
this.name = name;
this.c = c;
}
override string toString() const {
return format("{a: %s, name: %s, c: %s}", a, name, c);
}
}
```
Questions:
1. Is it necessary to pad myPaddedClassSize to an 8 byte
granularity on 64 bit machine?
If so, should emplace() be modified to provide the padding
internally?
2. There is a 16 byte header before myClasses[0].a
Is this for class overhead?
More information about the Digitalmars-d-learn
mailing list