Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Destroy destructor crashes?  (Read 13340 times)

0 Members and 1 Guest are viewing this topic.

Nekroze

  • Newbie
  • *
  • Posts: 30
    • View Profile
Destroy destructor crashes?
« on: December 16, 2012, 03:40:49 pm »
Ok i am trying to wrap some classes in d with the csfml derelict bindings and naturally i want to destroy the sfml object with destructor however when i do that it crashes.

If i where to remove the destructor and have a manual destruction method to the class it doesnt crash if i where not to have a destructor or a destroy method and just leave the memory around it still works but the moment i use the destroy in a destructor it crashes.

It crashes with this error as reported by mago debugger:
Quote
First-chance exception: core.exception.InvalidMemoryOperationError

I dont understand why this happens inside a destructor but not in a method that does the same thing. Here is my test code about as minimal as i can make it to demonstrate:

module main;

import derelict.sfml2.system;
import derelict.sfml2.window;
import derelict.sfml2.graphics;
pragma(lib, "derelictUtil.lib");
pragma(lib, "derelictSFML2.lib");

class Image {
        sfImage* image;

        this(uint width, uint height) {
                image = sfImage_create(width, height);
        }

        ~this() {
                this.destroy();
        }

        void destroy() {
                sfImage_destroy(image);
        }
}

void main() {
        DerelictSFML2System.load();
        DerelictSFML2Window.load();
        DerelictSFML2Graphics.load();

        auto image = sfImage_create(100, 100);
        sfImage_destroy(image);

        auto myimage = new Image(100, 100);
        //myimage.destroy();
}

Can anyone tell my why this is happening and or how to fix it?

Jebbs

  • Sr. Member
  • ****
  • Posts: 358
  • DSFML Developer
    • View Profile
    • Email
Re: Destroy destructor crashes?
« Reply #1 on: December 16, 2012, 10:37:53 pm »
Hmm... I wonder how many people are working on wrappers, haha.

In any cast, this is a garbage collection issue. You don't actually have to call sfXXX_destroy on anything. The error is given because you deleted the pointer manually, and garbage collection is trying to delete it directly after. I think you get a similar runtime error in C++ when you try to delete a null/empty pointer.
DSFML - SFML for the D Programming Language.

Nekroze

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: Destroy destructor crashes?
« Reply #2 on: December 17, 2012, 05:08:38 am »
But am i right in thinking however that if i don't call sfImage_destroy on the classes contained image then it will sit in memory forever? i thought the sfImage was created in C/C++ so its not garbage colleted by D?

That's what i thought so it just seemed natural then to destroy the image in a destructor.

PS: I am not creating an OO wrapper for Derelict SFML as much as i would love one, i just want to have a class that uses and clears the memory of sfml objects properly and as much as i may be silly in what i am doing i just thought that this was the way to do it but i was wrong so i am not sure what to do.


aldacron

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: Destroy destructor crashes?
« Reply #3 on: December 17, 2012, 05:42:15 am »
Please see my answer to your post in the D newsgroups.

Jebbs

  • Sr. Member
  • ****
  • Posts: 358
  • DSFML Developer
    • View Profile
    • Email
Re: Destroy destructor crashes?
« Reply #4 on: December 17, 2012, 09:56:17 am »
I just wanted to post in here letting people know that my answer is incorrect.

In this case, the error
Quote
First-chance exception: core.exception.InvalidMemoryOperationError

Is caused by the Derelict library unloading the .dll's before the objects are deleted. Since the Derelict maps the functions to function pointers, when Derelict unloads first the function sfImage_destroy no longer exists and we get the error.

As soon as I am 100% sure of what we should be doing when wrapping sfObjects in a D class, I will post it here for others to know!
DSFML - SFML for the D Programming Language.

aldacron

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: Destroy destructor crashes?
« Reply #5 on: December 17, 2012, 10:17:58 am »
Is caused by the Derelict library unloading the .dll's before the objects are deleted. Since the Derelict maps the functions to function pointers, when Derelict unloads first the function sfImage_destroy no longer exists and we get the error.

Derelict will *always* unload the library before any destructors are run. The library is unloaded in a module destructor. When an app is exiting, the D Runtime always calls module destructors before call the GC's cleanup method. So when the app exits, any objects still around in the GC that call into sfml (or any bound library) in the class destructor will always cause the app to crash because the DLL/so/dynlib will have been unloaded already.

Quote
As soon as I am 100% sure of what we should be doing when wrapping sfObjects in a D class, I will post it here for others to know!

The D documentation explicitly says not to rely on destructors to release system resources. Because objects are GCed, there is never any guarantee the destructors will be run. And when they *are* run, there's no guarantee in which order. My approach is to do it manually, with a little help from scope(exit). Others use structs or scoped objects (part of the language in D1, a Phobos template in D2) when possible to cleanup when an object goes out of scope. Personally, I just pretend the destructors don't even exist.

Nekroze

  • Newbie
  • *
  • Posts: 30
    • View Profile
Re: Destroy destructor crashes?
« Reply #6 on: December 17, 2012, 12:56:59 pm »
That all makes sense, apologies for not thinking of the module unloading.

The idea of using a struct seems tempting but structs are stored on the stack aren't they, so i don't think i would do this for my classes as they are generally long life span objects.

So i guess i will just go with a manual destroy method.

Thanks guys for all the support. Cant wait for an OO wrapper in D based on derelict3!

Jebbs

  • Sr. Member
  • ****
  • Posts: 358
  • DSFML Developer
    • View Profile
    • Email
Re: Destroy destructor crashes?
« Reply #7 on: December 17, 2012, 11:17:15 pm »
Others use structs or scoped objects (part of the language in D1, a Phobos template in D2) when possible to cleanup when an object goes out of scope. Personally, I just pretend the destructors don't even exist.

A scoped object wouldn't be a part of the GC, would it? This sounds more like a RAII technique to me. And like Nekroze was wondering, they would be allocated on the stack instead of the heap, correct? That said, if we were to use the sfXXX objects directly, they would be allocated on the stack anyways so using a struct or scoped object doesn't sound like the worst thing to do even if they are long-lived.
« Last Edit: December 18, 2012, 12:15:09 am by Jebbs »
DSFML - SFML for the D Programming Language.

aldacron

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: Destroy destructor crashes?
« Reply #8 on: December 18, 2012, 02:32:02 am »
A scoped object wouldn't be a part of the GC, would it? This sounds more like a RAII technique to me.

That is correct.

Quote
And like Nekroze was wondering, they would be allocated on the stack instead of the heap, correct?

Correct.

Quote
That said, if we were to use the sfXXX objects directly, they would be allocated on the stack anyways so using a struct or scoped object doesn't sound like the worst thing to do even if they are long-lived.

It's really going to complicate your game design. All of your scoped objects would have to be declared in a function. Then you'd have to create a scheme to share them with the rest of the program. It would create a whole host of challenges for things like level loading.

This sort of technique is only useful for things you need inside a specific scope. It's not going to be useful at all for anything that lives for the life of the program.

Jebbs

  • Sr. Member
  • ****
  • Posts: 358
  • DSFML Developer
    • View Profile
    • Email
Re: Destroy destructor crashes?
« Reply #9 on: December 18, 2012, 03:53:13 am »
You are very right. Scoped classes will not work for this kind of thing. There's just too much going on, and I didn't understand the semantics of using the scope attribute well enough.

I do agree that manually unloading all resources for D classes containing CSFML pointers is the best way to prevent memory leaks. I apologize if this was a frustrating point to get across to me. I just like to fully understand all the details before I implement a concept into code. :P


DSFML - SFML for the D Programming Language.