Jump to page: 1 2
Thread overview
free causes exception
Jan 26, 2016
Igor
Jan 26, 2016
Daniel Kozak
Jan 26, 2016
Igor
Jan 26, 2016
Daniel Kozak
Jan 26, 2016
Ali Çehreli
Jan 26, 2016
Igor
Jan 26, 2016
Ali Çehreli
Jan 27, 2016
Kagamin
Jan 26, 2016
Igor
Jan 26, 2016
ZombineDev
Jan 26, 2016
ZombineDev
Jan 27, 2016
Mike Parker
Jan 27, 2016
Igor
January 26, 2016
I have successfully malloc'ed an object but when I go to free it in the destructor I get an exception. The destructor simply has

~this() // destructor for Foo
{
    core.stdc.stdlib.free(&this);
}


auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, App))[0..__traits(classInstanceSize, App)];
auto app = cast(App)emplace!App(buffer[]);

I tried to retain a ptr to buffer and free that but still no good. I also get a depreciation warning that &this is not an lvalue. Hopefully I don't have to keep a ptr around to this simply to free it and avoid future issues?

So how am I suppose to free an object?


January 26, 2016
V Tue, 26 Jan 2016 14:20:29 +0000
Igor via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
napsáno:

> I have successfully malloc'ed an object but when I go to free it in the destructor I get an exception. The destructor simply has
> 
> ~this() // destructor for Foo
> {
>      core.stdc.stdlib.free(&this);
> }
> 
> 
> auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize,
> App))[0..__traits(classInstanceSize, App)];
> auto app = cast(App)emplace!App(buffer[]);
> 
> I tried to retain a ptr to buffer and free that but still no good. I also get a depreciation warning that &this is not an lvalue. Hopefully I don't have to keep a ptr around to this simply to free it and avoid future issues?
> 
> So how am I suppose to free an object?
> 
> 

core.stdc.stdlib.free(cast(void *)this);



January 26, 2016
On Tuesday, 26 January 2016 at 14:48:48 UTC, Daniel Kozak wrote:
> V Tue, 26 Jan 2016 14:20:29 +0000
> Igor via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> napsáno:
>
>> [...]
>
> core.stdc.stdlib.free(cast(void *)this);

I still get an exception:

Exception thrown at 0x00007FF6C7CA3700 in test.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
January 26, 2016
V Tue, 26 Jan 2016 15:24:00 +0000
Igor via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
napsáno:

> On Tuesday, 26 January 2016 at 14:48:48 UTC, Daniel Kozak wrote:
> > V Tue, 26 Jan 2016 14:20:29 +0000
> > Igor via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> > napsáno:
> > 
> >> [...]
> >
> > core.stdc.stdlib.free(cast(void *)this);
> 
> I still get an exception:
> 
> Exception thrown at 0x00007FF6C7CA3700 in test.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

Can you post full code?

January 26, 2016
On 01/26/2016 06:20 AM, Igor wrote:
> I have successfully malloc'ed an object but when I go to free it in the
> destructor I get an exception. The destructor simply has
>
> ~this() // destructor for Foo
> {
>      core.stdc.stdlib.free(&this);
> }

That design suggests a complexity regarding object responsibilities: Assuming that the object was constructed on a piece of memory that it did *not* allocate, the memory was owned by somebody else. In that case and in general, freeing the memory should be the responsibility of that other somebody as well.

Even if it is acceptable, you must also make sure that opAssign() and post-blit do the right thing: no two object should own the same piece of memory.

Ali

January 26, 2016
On 1/26/16 9:20 AM, Igor wrote:
> I have successfully malloc'ed an object but when I go to free it in the
> destructor I get an exception. The destructor simply has
>
> ~this() // destructor for Foo
> {
>      core.stdc.stdlib.free(&this);
> }
>
>
> auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize,
> App))[0..__traits(classInstanceSize, App)];
> auto app = cast(App)emplace!App(buffer[]);
>
> I tried to retain a ptr to buffer and free that but still no good. I
> also get a depreciation warning that &this is not an lvalue. Hopefully I
> don't have to keep a ptr around to this simply to free it and avoid
> future issues?
>
> So how am I suppose to free an object?

Don't do it in the destructor.

I can only imagine that you are triggering the destructor with destroy? In this case, destroy is calling the destructor, but then tries to zero the memory (which has already been freed).

There is a mechanism D supports (but I believe is deprecated) by overriding new and delete. You may want to try that. It's deprecated, but has been for years and years, and I doubt it's going away any time soon.

A class shouldn't care how it's allocated or destroyed. That is for the memory manager to worry about.

-Steve

January 26, 2016
On Tuesday, 26 January 2016 at 19:34:22 UTC, Ali Çehreli wrote:
> On 01/26/2016 06:20 AM, Igor wrote:
> > I have successfully malloc'ed an object but when I go to free
> it in the
> > destructor I get an exception. The destructor simply has
> >
> > ~this() // destructor for Foo
> > {
> >      core.stdc.stdlib.free(&this);
> > }
>
> That design suggests a complexity regarding object responsibilities: Assuming that the object was constructed on a piece of memory that it did *not* allocate, the memory was owned by somebody else. In that case and in general, freeing the memory should be the responsibility of that other somebody as well.
>
> Even if it is acceptable, you must also make sure that opAssign() and post-blit do the right thing: no two object should own the same piece of memory.
>
> Ali

That shouldn't be the case. I allocate in a static method called New once. I then deallocate in the destructor. Basically just as one would do in C++.

I'm not sure about opAssign and post-blit


class Foo
{
    ~this() // destructor for Foo
    {
		core.stdc.stdlib.free(cast(void *)this);
    }

        // Creates a Foo
	static public Foo New()
	{				
		auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize, Foo))[0..__traits(classInstanceSize, Foo)];
		auto app = cast(Foo)emplace!Foo(buffer[]);
        }
}

hence

auto f = Foo.New();

then .destroy(f);

which is where the crash happens. If I don't destroy, it works fine + memory leak.

		
January 26, 2016
On Tuesday, 26 January 2016 at 20:17:20 UTC, Steven Schveighoffer wrote:
> On 1/26/16 9:20 AM, Igor wrote:
>> I have successfully malloc'ed an object but when I go to free it in the
>> destructor I get an exception. The destructor simply has
>>
>> ~this() // destructor for Foo
>> {
>>      core.stdc.stdlib.free(&this);
>> }
>>
>>
>> auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize,
>> App))[0..__traits(classInstanceSize, App)];
>> auto app = cast(App)emplace!App(buffer[]);
>>
>> I tried to retain a ptr to buffer and free that but still no good. I
>> also get a depreciation warning that &this is not an lvalue. Hopefully I
>> don't have to keep a ptr around to this simply to free it and avoid
>> future issues?
>>
>> So how am I suppose to free an object?
>
> Don't do it in the destructor.
>
> I can only imagine that you are triggering the destructor with destroy? In this case, destroy is calling the destructor, but then tries to zero the memory (which has already been freed).
>
> There is a mechanism D supports (but I believe is deprecated) by overriding new and delete. You may want to try that. It's deprecated, but has been for years and years, and I doubt it's going away any time soon.
>
> A class shouldn't care how it's allocated or destroyed. That is for the memory manager to worry about.

um? Memory manager? I am doing it manually C++ style so I don't have to worry about the god forsaken memory manager. Why is it so difficult? I create the object and release it when I need to.

I can replace the destroy(f) with free(inline the code) but I don't see why that should matter. The whole point of destructors is to do this sort of stuff. That's why they were invented in the first place!?!




January 26, 2016
On Tuesday, 26 January 2016 at 21:23:28 UTC, Igor wrote:
> On Tuesday, 26 January 2016 at 20:17:20 UTC, Steven Schveighoffer wrote:
>> On 1/26/16 9:20 AM, Igor wrote:
>>> I have successfully malloc'ed an object but when I go to free it in the
>>> destructor I get an exception. The destructor simply has
>>>
>>> ~this() // destructor for Foo
>>> {
>>>      core.stdc.stdlib.free(&this);
>>> }
>>>
>>>
>>> auto buffer = core.stdc.stdlib.malloc(__traits(classInstanceSize,
>>> App))[0..__traits(classInstanceSize, App)];
>>> auto app = cast(App)emplace!App(buffer[]);
>>>
>>> I tried to retain a ptr to buffer and free that but still no good. I
>>> also get a depreciation warning that &this is not an lvalue. Hopefully I
>>> don't have to keep a ptr around to this simply to free it and avoid
>>> future issues?
>>>
>>> So how am I suppose to free an object?
>>
>> Don't do it in the destructor.
>>
>> I can only imagine that you are triggering the destructor with destroy? In this case, destroy is calling the destructor, but then tries to zero the memory (which has already been freed).
>>
>> There is a mechanism D supports (but I believe is deprecated) by overriding new and delete. You may want to try that. It's deprecated, but has been for years and years, and I doubt it's going away any time soon.
>>
>> A class shouldn't care how it's allocated or destroyed. That is for the memory manager to worry about.
>
> um? Memory manager? I am doing it manually C++ style so I don't have to worry about the god forsaken memory manager. Why is it so difficult? I create the object and release it when I need to.
>
> I can replace the destroy(f) with free(inline the code) but I don't see why that should matter. The whole point of destructors is to do this sort of stuff. That's why they were invented in the first place!?!

Why not simply:
class Foo { this(Arg1, Arg2) { ... } ... }

// Option A:
import std.typecons : scoped;
auto foo = scoped!Foo(arg1, arg2);

// Option B:
import std.experimental.allocator : make, dispose;
import std.experimental.allocator.mallocator;
auto foo = Mallocator.instance.make!Foo(arg1, arg2);
scope(exit) Mallocator.instance.dispose(foo);

http://dlang.org/phobos/std_typecons#.scoped
http://dlang.org/phobos/std_experimental_allocator
January 26, 2016
On Tuesday, 26 January 2016 at 21:23:28 UTC, Igor wrote:
> On Tuesday, 26 January 2016 at 20:17:20 UTC, Steven Schveighoffer wrote:
>> On 1/26/16 9:20 AM, Igor wrote:
>>> [...]
>>
>> Don't do it in the destructor.
>>
>> I can only imagine that you are triggering the destructor with destroy? In this case, destroy is calling the destructor, but then tries to zero the memory (which has already been freed).
>>
>> There is a mechanism D supports (but I believe is deprecated) by overriding new and delete. You may want to try that. It's deprecated, but has been for years and years, and I doubt it's going away any time soon.
>>
>> A class shouldn't care how it's allocated or destroyed. That is for the memory manager to worry about.
>
> um? Memory manager? I am doing it manually C++ style so I don't have to worry about the god forsaken memory manager. Why is it so difficult? I create the object and release it when I need to.
>
> I can replace the destroy(f) with free(inline the code) but I don't see why that should matter. The whole point of destructors is to do this sort of stuff. That's why they were invented in the first place!?!

Destructors are meant to destroy the members of the object, not the object itself. An object should be freed by the destructor of its owner and so on, transitively.
A class should not have a hard coded dependency on malloc/free, or the GC. You should strive to design it in such a way that the clients of the class are free to decide how to manage its memory.
« First   ‹ Prev
1 2