I'm new to D. I have some modest knowledge of C++, but am more familiar with scripting languages (Matlab, Python, R). D seems so much easier than C++ in a lot of ways (and I just learned about rdmd today, which is pretty cool). I am concerned about performance of D vs. C++, so I wanted to learn a little bit more about manual memory management, in case I might ever need it (not for any particular application).

The D Language book Section 6.3.4-5 covers the topic. I basically copied below and made some small changes.

import core.stdc.stdlib;
import std.stdio;

class Buffer {
        private void* data;
        // Constructor
        this()
        {
            data = malloc(1024);
        }
        // Destructor
        ~this()
        {
            free(data);
        }
}
unittest {
        auto b = new Buffer;
        auto b1 = b;
        destroy(b); //changed from clear in book example
        assert(b1.data is null);
        writeln("Unit Test Finished");
}

I was thinking that it might be cool to use scope(exit) to handle the memory management. It turns out the below unit test works.

unittest {
        auto b = new Buffer;
        scope(exit) destroy(b);
        writeln("Unittest Finished");
}

However, if you leave in the auto b1 and assert, then it fails. I suspect this is for the same reason that shared pointers are a thing in C++ (it can't handle copies of the pointer).

Alternately, you can use some other scope and something like this
unittest {
        {
                Buffer b = new Buffer;
                scope(exit) destroy(b);
        }
        destroy(b);
        writeln("Unittest Finished");
}

will fail because b has already been destroyed. I thought this behavior was pretty cool. If you followed this approach, then you wouldn't have to wait until the end of the program to delete the pointers. The downside would be if you need to write a lot of pointers and there would be a lot of nesting. (likely the motivation for the reference counting approach to smart pointers).

I wasn't sure how to figure out a way to combine these two components so that I only have to write one line. I thought one approach might be to put a scope(exit) within the constructor, but that doesn't work. Also, if I try to do it within a template function, then the scope(exit) is limited to the function scope, which isn't the same thing.

Outside of writing a unique_ptr template class (which I have tried to do, but couldn't get it to work) I don't really know how to combine them into one line. Any ideas?

Reply via email to