Ownership semantics

Matt Elkins via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jan 31 12:01:04 PST 2016


On Sunday, 31 January 2016 at 19:34:43 UTC, maik klein wrote:
> I recently asked a question about ownership semantics in D 
> https://stackoverflow.com/questions/35115702/how-do-i-express-ownership-semantics-in-d
>
> But a few minutes ago I found an answer on SO that could 
> potentially explain a lot.
>
> http://stackoverflow.com/a/35114945/944430
>
> Sadly it has some pseudo code in it so I implemented it with 
> std.experimental.allocator
>
> struct UniquePtr(T) {
>     import std.experimental.allocator;
>     private T* ptr = null;
>
>     @disable this(this); // This disables both copy 
> construction and opAssign
>
>     this(Args...)(auto ref Args args){
>         ptr = theAllocator.make!T(args);
>     }
>
>     ~this() {
>         theAllocator.dispose(ptr);
>     }
>
>     inout(T)* get() inout {
>         return ptr;
>     }
>
>     // Move operations
>     this(UniquePtr!T that) {
>         this.ptr = that.ptr;
>         that.ptr = null;
>     }
>
>     ref UniquePtr!T opAssign(UniquePtr!T that) { // Notice no 
> "ref" on "that"
>         import std.algorithm.mutation;
>         swap(this.ptr, that.ptr); // We change it anyways, 
> because it's a temporary
>         return this;
>     }
> }
>
> Is this code correct? One problem that I have is
>
> UniquePtr!int[int] map;
>
> will result in a memory exception and I have no idea why.

Interesting. It is something in the dispose, because I changed 
the destructor to:

[code]
~this()
{
         writeln("Disposing ", ptr, " for this ", &this);
         theAllocator.dispose(ptr);
         writeln("Disposed ", ptr, " for this ", &this);
}
[/code]

And I only get the disposing line, not the disposed.

I tried taking my ResourceHandle struct that I pasted to you in 
the other thread earlier and doing the same operation with it (I 
had to change a const to inout and remove an extraneous 'in' 
marker to make it compile):

[code]
alias RH = ResourceHandle!(int*, (int* ptr) 
{theAllocator.dispose(ptr);});
RH[int] otherMap;
otherMap[3] = RH(theAllocator.make!int(5));
[/code]

and I get the same invalid memory operation. With either class, I 
avoid the error if I use a stack member or a static array, but 
with the associative array or just a dynamic array I get the 
problem.

To see it in a dynamic array:
[code]
auto map = new UniquePtr!int[1];
map[0] = UniquePtr!int(5);
[/code]

Not sure what it is...still playing with it.


More information about the Digitalmars-d-learn mailing list