Instantiating Class Objects Elsewhere Than the GC Heap

From D Wiki
Revision as of 11:15, 26 February 2014 by Verax (talk | contribs)
Jump to: navigation, search

Class objects in D are normally allocated on the garbage collected (GC) heap. In some circumstances it may be desirable to instantiate them on some other heap, such as the C runtime library's heap. The normal way to do this is to overload the new and delete operators for that class; but if that is not practical the following will work.

This technique goes "under the hood" of how D works, and as such it is not guaranteed to work with every D compiler. In particular, how the constructors and destructors are called is not necessarilly portable.

Here's a module that does just that:

import std.c.stdlib;
import std.outofmemory;

// This is part of the D internal runtime library support
extern (C) void _d_callfinalizer(void *p);

class Foo
{
	this(int x, char c) { ... }
	~this() { ... }
}

Foo alloc_Foo(int x, char c)
{
	ClassInfo ci = Foo.classinfo;
	Foo f;
	void *p;

	p = std.c.stdlib.malloc(ci.init.length);
	if (!p)
	std.outofmemory._d_OutOfMemory();

	// Initialize it
	(cast(byte*)p)[0 .. ci.init.length] = ci.init[];

	f = cast(Foo)p;

	// Run constructor on it
	f._ctor(x, c);

	return f;
}

void free_Foo(Foo f)
{   void* p = cast(void*)f;

	if (p)
	{
	_d_callfinalizer(p);	// call destructor
	std.c.stdlib.free(p);
	}
}


This article was originally published at http://digitalmars.com/techtips/class_objects.html.