Call destructor directly.
Agustin
agustin.l.alvarez at hotmail.com
Mon Oct 21 07:59:26 PDT 2013
On Monday, 21 October 2013 at 07:31:30 UTC, Ali Çehreli wrote:
> On 10/20/2013 10:59 PM, Agustin wrote:
>
> > That didn't work, but after reading how emplace works, i had
> to make
> > some changes.
> >
> > public T allocate(T : Object, A...)(auto ref A
> arguments) {
> > auto pMemory =
> rawAllocate(__traits(classInstanceSize, T),
> > T.alignof);
>
> Does rawAllocate still return void*? For classes, emplace
> requires (or at least "also accepts" a slice).
>
> Your code will be simpler if rawAllocate returned a slice:
>
> import std.conv;
>
> void[] rawAllocate(size_t, size_t)
> {
> static ubyte[1000] buffer;
> return buffer;
> }
>
> T allocate(T : Object, A...)(auto ref A arguments) {
> auto pMemory = rawAllocate(__traits(classInstanceSize, T),
> T.alignof);
>
> return emplace!T(pMemory, arguments);
> }
>
> class C
> {
> this(int i, double d)
> {}
> }
>
> void main()
> {
> auto c = allocate!C(42, 1.5);
> }
>
> If it has to return void*, you can make a slice from a plain
> pointer with the following syntax:
>
> void * rawAllocate(size_t, size_t)
> {
> static ubyte[1000] buffer;
> return buffer.ptr;
> }
>
> import std.stdio;
>
> void main()
> {
> enum requiredLength = 42;
> auto rawPtr = rawAllocate(requiredLength, 16);
> auto slice = rawPtr[0..requiredLength]; // <-- slice from
> plain pointer
> writeln(slice);
> }
>
> Ali
Thanks!, i didn't knew i could do that, void[] sounds like an
array of nothing :P.
On Monday, 21 October 2013 at 11:48:11 UTC, Benjamin Thaut wrote:
> Am 21.10.2013 04:17, schrieb Adam D. Ruppe:
>> On Monday, 21 October 2013 at 02:06:02 UTC, Agustin wrote:
>>> I'm implementing some custom memory allocator, is possible to
>>> call an
>>> object destructor directly?
>>
>>
>> destroy(object);
>>
>> destroy is in the automatically imported object.dm so you
>> don't have to
>> import anything,
>>
>> The source code is in dmd2/src/druntime/src/object_.d, there's
>> a few
>> overloads if you are curious how it is implemented. Short
>> answer is
>> there's a pointer to the destructor in the TypeInfo and
>> destroy calls it.
>
> Using destroy will zero the entire memory block after
> destroying the object. If you are freeing the memory right
> after destroying this is going to cost you performance.
>
> To avoid this declare:
>
> extern (C) void rt_finalize2(void* p, bool det = true, bool
> resetMemory = true);
>
> and then call
>
> rt_finalize(cast(void*)object, false, false);
>
> Also if you want to give a nice error message in case you are
> calling a construcor that does not exist you should take a look
> at my AllocatorNew function:
>
> https://github.com/Ingrater/druntime/blob/merge64/src/core/allocator.d#L616
>
> Doing it the way emplace does will just result in a error
> message
>
> "Dont know how to initialize a object of type YourObject"
>
> With some meta programming you can get error messages like:
>
> "Dont know how to initialize a object of type YourObject
> Available constructors:
> this(int, int)
> this(float)
> this(void*)"
>
> Kind Regards
> Benjamin Thaut
I just need to call the destructor of the class since the memory
of the allocators is released at the end of the application.
// Pre allocate 1GB.
auto pMemory = GC.malloc(1_048_576 * 1000,
GC.BlkAttr.NONE);
// Allocate a linear allocator of 10MB.
auto pLinearAllocator = new LinearAllocator(1_048_576 *
10, pMemory);
// Allocates a pool allocator of 50MB.
auto pMemoryBlock = pMemory + 1_048_576 * 10;
auto pPoolAllocator = new
PoolAllocator!MyComponent(1_048_576 * 50, pMemory + 1_048_576 *
10);
// Game loop, etc.
// ..... (When a object is called to release, it won't
release its memory rather than cache the entry and call the
object destructor. Releasing the object from GC
// end of game
exit() // Allocators are released here, because GC will
not find any reference to it, and will call any object destructor
left.
More information about the Digitalmars-d-learn
mailing list