SFML community forums

Help => Graphics => Topic started by: ThreeDumps on October 17, 2012, 12:24:55 pm

Title: [SFML 2.0] Strange unhandled exception
Post by: ThreeDumps on October 17, 2012, 12:24:55 pm
Hello!

I have one problem.

#include <SFML/Graphics.hpp>

struct CFontd
{
    sf::Font * font;
    CFontd() {  
                font = new sf::Font();
                font->loadFromFile( "arial.ttf" );  
        }
} Font;

struct CFont
{
        sf::Text Text;
    CFont() {
                Text.setFont( *Font.font );
                Text.setString( "0" );
    }
};

int main() {
        CFont Test;
    sf::RenderWindow App( sf::VideoMode( 800, 600 ), "SFML works!" );
    while( App.isOpen() )
    {
        sf::Event ev;
        while( App.pollEvent( ev ) )
        {
            if( ev.type == sf::Event::Closed || ev.type == sf::Event::KeyPressed )
                 App.close();
           
        }
        App.display();
    }
    return 0;
}
 

All goes ok. But when I change implementation of CFontd class to

struct CFontd
{
    sf::Font font;
    CFontd() {  
        font.loadFromFile( "arial.ttf" );  
        }
} Font;

and of course
CFont() {
                Text.setFont( Font.font );
                Text.setString( "0" );
    }
I get unhandled exception after press any key (so i get ue when app closes).

So my question is: Why I can't use local "sf::Font" object in global objects?
Title: Re: [SFML 2.0] Strange unhandled exception
Post by: binary1248 on October 17, 2012, 12:57:18 pm
This is the same problem as all those reports of crashing on close because of the default font being used. The default font got removed lately, so now it isn't the library's fault if your application crashes, it is yours :). Basically to avoid the crash make sure you destroy all fonts before your window is destroyed. This in turn means never use sf::Font in global or static data structures. This is something one should avoid anyway, as it is generally regarded as bad programming practice. The reason your first variant doesn't crash is actually more scary than the second variant crashing. You let the font leak in the first variant because you don't explicitly call delete on it, ever... Since its destructor is never called you also don't experience a crash but leak a few thousand bytes in the process. Just because something doesn't crash, doesn't mean it is correct ;).
Title: Re: [SFML 2.0] Strange unhandled exception
Post by: ThreeDumps on October 17, 2012, 01:25:08 pm
Quote
You let the font leak in the first variant because you don't explicitly call delete on it
I'm using this font in whole app. After closing the application, the system should take care of this. So it's only theoretical leak.

Quote
This in turn means never use sf::Font in global or static data structures.
So... It's impossible to create simple global atlas with fonts? And I must make global pointer and create object in main() and delete it before app.close() ?

Quote
it is generally regarded as bad programming practice

Hm... Better will be in many constructors use that:

CClass(CGame *, CGraph *, CTilesets *, CFonts *, CAudio *, /* finally normal data 3-5 vars */)
(CGame - game data info, CGraph - atlas of textures, CTileset - atlas of tilesets, etc)
then use some global singletons ;> ?
Title: Re: [SFML 2.0] Strange unhandled exception
Post by: Nexus on October 17, 2012, 02:43:59 pm
I'm using this font in whole app. After closing the application, the system should take care of this. So it's only theoretical leak.
That is your assumption which is not true in every case. Resource deallocation does not only include memory, but also other resources like file handles, network connections, or any code that is written in the destructors. Since resource leaks are usually extremely easy to avoid, there is no reason to find an excuse, just use RAII and automatic variables ;)

then use some global singletons ;> ?
No. Try to avoid global variables completely, as well as singletons. In C++, it is really not that difficult to write code without them. It may look less comfortable in the beginning, but it safes you a lot of trouble in the long term. The troubles are explained here (http://en.sfml-dev.org/forums/index.php?topic=5187.msg34227#msg34227).
Title: Re: [SFML 2.0] Strange unhandled exception
Post by: Laurent on October 17, 2012, 03:26:01 pm
Note that accessing a variable globally doesn't mean that it has to be constructed/destroyed at global scope.

So a compromise is to provide global access to your objects (with global functions), but initialize and destroy them at the right place (i.e. in the scope of the main function).
Title: Re: [SFML 2.0] Strange unhandled exception
Post by: Nexus on October 17, 2012, 05:18:31 pm
By the way, this C prefix is also something very questionable. It was originally used as a prefix for the MFC library, as a sort of namespace. Unfortunately, some people had the bad idea to adopt it. In short, the intention of the C prefix is to recognize classes faster, but this isn't possible in C++ which its load of abstractions. Imagine a typedef to a class, should it also contain "C"?
That's not even the whole problem, there are also templates or structs, for example. You need to ask yourself the question what advantage you effectively get by the C prefix. Recognizing classes isn't as helpful as you may think -- in the cases where you need to know that, you also need to know more (e.g. what interface does the class offer). As it is not possible to apply this naming convention consistently, I consider it more rational to omit Hungarian notation prefixes. Expressive identifiers and modern code style are much more helpful to understand code.