Jump to page: 1 2 3
Thread overview
D Beginner Trying Manual Memory Management
Jan 12, 2015
jmh530
Jan 12, 2015
ketmar
Jan 12, 2015
jmh530
Jan 12, 2015
ketmar
Jan 12, 2015
aldanor
Jan 12, 2015
ketmar
Jan 12, 2015
aldanor
Jan 13, 2015
ketmar
Jan 13, 2015
aldanor
Jan 13, 2015
ketmar
Jan 13, 2015
Laeeth Isharc
Jan 13, 2015
ketmar
Jan 13, 2015
aldanor
Jan 13, 2015
ketmar
Jan 14, 2015
Laeeth Isharc
Jan 14, 2015
aldanor
Jan 14, 2015
Laeeth Isharc
Jan 14, 2015
aldanor
Jan 14, 2015
Laeeth Isharc
Jan 13, 2015
ketmar
Jan 12, 2015
jmh530
Jan 13, 2015
ketmar
Jan 12, 2015
Mike
January 12, 2015
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?
January 12, 2015
On Mon, 12 Jan 2015 19:29:53 +0000
jmh530 via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

the proper answer is too long to write (it will be more an article that a forum answer ;-), so i'll just give you some directions:

  import std.typecons;

  {
    auto b = scoped!B(); // `auto` is important here!
    ...
  }

`scoped!` allocating class instance *on* *stack*, and automatically calls destructor when object goes out of scope.

but you'd better consider using struct for such things, as struct are stack-allocated by default (unlike classes, which are reference type and should be allocated manually).

there is a big difference between `class` and `struct` in D, much bigger that in C++ (where it's only about default protection, actually).


January 12, 2015
Thanks for the reply, I wasn't familiar with scoped. I was aware that structs are on the stack and classes are on the heap in D, but I didn't know it was possible to put a class on the stack. Might be interesting to see how this is implemented.

After looking up some more C++, I think what I was trying to do is more like make_unique than unique_ptr.

On Monday, 12 January 2015 at 19:42:14 UTC, ketmar via Digitalmars-d-learn wrote:
> On Mon, 12 Jan 2015 19:29:53 +0000
> jmh530 via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> wrote:
>
> the proper answer is too long to write (it will be more an article that
> a forum answer ;-), so i'll just give you some directions:
>
>   import std.typecons;
>
>   {
>     auto b = scoped!B(); // `auto` is important here!
>     ...
>   }
>
> `scoped!` allocating class instance *on* *stack*, and automatically
> calls destructor when object goes out of scope.
>
> but you'd better consider using struct for such things, as struct are
> stack-allocated by default (unlike classes, which are reference type
> and should be allocated manually).
>
> there is a big difference between `class` and `struct` in D, much
> bigger that in C++ (where it's only about default protection,
> actually).

January 12, 2015
On Mon, 12 Jan 2015 20:14:19 +0000
jmh530 via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> Thanks for the reply, I wasn't familiar with scoped. I was aware that structs are on the stack and classes are on the heap in D, but I didn't know it was possible to put a class on the stack. Might be interesting to see how this is implemented.
actually, there is nothing complicated there (if you don't want to write an universal thing like `emplace!` ;-). it builds a wrapper struct big enough to hold class instance, copies class `.init` there and calls class' constructor. the rest of the magic is done by the compiler: when struct goes out of scope, compiler calls struct destructor, which in turn calls class destructor. ah, and it forwards all other requests with `alias this` trick.

> After looking up some more C++, I think what I was trying to do is more like make_unique than unique_ptr.
i don't remember C++ well, but nevertheless i encouraging you to take a look at `std.typecons`. there are some handy things there, like `Rebindable!` or `Nullable!`. and some funny things like `BlackHole!` and `WhiteHole!`. ;-)

it even has `RefCounted!`, but it doesn't play well with classes yet
(AFAIR).


January 12, 2015
On Monday, 12 January 2015 at 20:30:45 UTC, ketmar via Digitalmars-d-learn wrote:
> it even has `RefCounted!`, but it doesn't play well with classes yet
> (AFAIR).
I wonder if it's possible to somehow make a version of refcounted that would work with classes (even if limited/restricted in some certain ways), or is it just technically impossible because of reference semantics?
January 12, 2015
On Mon, 12 Jan 2015 21:37:27 +0000
aldanor via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> On Monday, 12 January 2015 at 20:30:45 UTC, ketmar via Digitalmars-d-learn wrote:
> > it even has `RefCounted!`, but it doesn't play well with
> > classes yet
> > (AFAIR).
> I wonder if it's possible to somehow make a version of refcounted that would work with classes (even if limited/restricted in some certain ways), or is it just technically impossible because of reference semantics?
it's hard. especially hard when you considering inheritance (which is not playing well with templates) and yes, ref semantics.

on the other side i found myself rarely using classes at all. i mostly writing templates that checks if a passed "thing" has all the neccessary methods and properties in place and just using that. with D metaprogramming abilities (and `alias this` trick ;-) inheritance becomes not so important. and so classes too. sometimes i'm using structs with delegate fields to simulate some sort of "virtual methods" 'cause i tend to constantly forgetting about that `class` thingy. ;-)

OOP is overrated. at least c++-like (should i say "simula-like"?)
OOP. ;-)


January 12, 2015
On Monday, 12 January 2015 at 21:54:51 UTC, ketmar via Digitalmars-d-learn wrote:
> On Mon, 12 Jan 2015 21:37:27 +0000
> aldanor via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> wrote:
>
>> On Monday, 12 January 2015 at 20:30:45 UTC, ketmar via Digitalmars-d-learn wrote:
>> > it even has `RefCounted!`, but it doesn't play well with classes yet
>> > (AFAIR).
>> I wonder if it's possible to somehow make a version of refcounted that would work with classes (even if limited/restricted in some certain ways), or is it just technically impossible because of reference semantics?
> it's hard. especially hard when you considering inheritance (which is
> not playing well with templates) and yes, ref semantics.
>
> on the other side i found myself rarely using classes at all. i mostly
> writing templates that checks if a passed "thing" has all the
> neccessary methods and properties in place and just using that. with D
> metaprogramming abilities (and `alias this` trick ;-) inheritance
> becomes not so important. and so classes too. sometimes i'm using
> structs with delegate fields to simulate some sort of "virtual methods"
> 'cause i tend to constantly forgetting about that `class` thingy. ;-)
>
> OOP is overrated. at least c++-like (should i say "simula-like"?)
> OOP. ;-)
I see, thanks! :) I've started liking structs more and more recently as well and been pondering on how to convert a class-based code that looks like this (only the base class has any data):

class Base { T m_variable; }
class Common : Base { /* tons of methods; uses m_variable */ }
class Extra : Base { /* another ton of methods; uses m_variable */ }
class A : Extra, Common { ... }
class B : Common { ... }
class C : Extra { ... }

to refcounted structs with alias this but couldn't quite figure out how to do it (other than use mixin templates...). Even if the multiple alias this DIP was implemented, I don't think it would help much here :/
January 12, 2015
On Monday, 12 January 2015 at 19:29:54 UTC, jmh530 wrote:
> 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).
>

There is a good article on the D Wiki that covers this topic with several different patterns and working examples:

http://wiki.dlang.org/Memory_Management

I hope you'll find it helpful.

Mike
January 12, 2015
I had seen some stuff on alias thing, but I hadn't bothered to
try to understand it until now. If I'm understanding the first
example <a href="http://dlang.org/class.html#AliasThis">here</a>,
alias this let's you refer to x in s by writing either s.x (as
normally) or just s. That didn't seem that interesting, but then
I found <a href="http://3d.benjamin-thaut.de/?p=90">example</a>
where they alias this'ed a struct method. That's pretty
interesting.

OOP seems like a good idea, but every time I've written a bunch
of classes in C++ or Python, I inevitably wonder to myself why I
just spent 5 times as long doing something I could do with
functions. Then there's endless discussion about pimpl.

On Monday, 12 January 2015 at 21:54:51 UTC, ketmar via
Digitalmars-d-learn wrote:
> On Mon, 12 Jan 2015 21:37:27 +0000
> aldanor via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> wrote:
>
>> On Monday, 12 January 2015 at 20:30:45 UTC, ketmar via Digitalmars-d-learn wrote:
>> > it even has `RefCounted!`, but it doesn't play well with classes yet
>> > (AFAIR).
>> I wonder if it's possible to somehow make a version of refcounted that would work with classes (even if limited/restricted in some certain ways), or is it just technically impossible because of reference semantics?
> it's hard. especially hard when you considering inheritance (which is
> not playing well with templates) and yes, ref semantics.
>
> on the other side i found myself rarely using classes at all. i mostly
> writing templates that checks if a passed "thing" has all the
> neccessary methods and properties in place and just using that. with D
> metaprogramming abilities (and `alias this` trick ;-) inheritance
> becomes not so important. and so classes too. sometimes i'm using
> structs with delegate fields to simulate some sort of "virtual methods"
> 'cause i tend to constantly forgetting about that `class` thingy. ;-)
>
> OOP is overrated. at least c++-like (should i say "simula-like"?)
> OOP. ;-)
January 13, 2015
On Mon, 12 Jan 2015 23:06:16 +0000
jmh530 via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> I had seen some stuff on alias thing, but I hadn't bothered to try to understand it until now. If I'm understanding the first example <a href="http://dlang.org/class.html#AliasThis">here</a>, alias this let's you refer to x in s by writing either s.x (as normally) or just s. That didn't seem that interesting, but then I found <a href="http://3d.benjamin-thaut.de/?p=90">example</a> where they alias this'ed a struct method. That's pretty interesting.
there is nice page by p0nce and it shows nice and simple `alias this` trick usage: http://p0nce.github.io/d-idioms/#Extending-a-struct-with-alias-this

and i have "stream.d" module in my IV package
( http://repo.or.cz/w/iv.d.git/tree ), which works with "i/o streams"
by testing if passed struct/class has necessary methods (`isReadable!`,
`isWriteable!`, `isSeekable!`, etc.


« First   ‹ Prev
1 2 3