Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

04.02.2010, 22:40

SFML, ResourceManager und Heap Verletzung

Guten Abend,

ich erhalte bei jedem Beenden die Meldung einer Heap Verletzung. Als sorgfältiger Programmierer will ich dem natürlich nachgehen.

Es geht um diesen RessourceManager bzw. den ImageManager: http://www.sfml-dev.org/wiki/en/sources/resource_manager_hiura

Dieser ist in einer Klasse mit folgendem Code:

Application.hpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef APPLICATION_HPP
#define APPLICATION_HPP

#include <SFML/Graphics.hpp>
#include "ImageManager.hpp"
#include "GameStateManager.hpp"

class Application
{
public:
    bool run;
    sf::RenderWindow screen;
    sftools::ImageManager imgm;
    GameStateManager gsm;

    Application();
    ~Application();

    void input();

    void logic();

    void render();
};


Application.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "Application.hpp"
#include "const.hpp"
#include "enum.hpp"

Application::Application()
{
    run = true;
    this->screen.Create(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP), "Bounce a ball against a wall.");
}

Application::~Application()
{
    //imgm.Destroy("img/logo.png"); Lösche ich das Bild manuell erscheint die Verletzung nicht.

}

void Application::input()
{
    this->gsm.currentState->input();
}
void Application::logic()
{
    this->gsm.currentState->logic();
    if(this->gsm.nextState == STATE_EXIT)
    {
        run = false;
    } else {
        this->gsm.changeState();
    }
}
void Application::render()
{
    this->screen.Clear();
    this->gsm.currentState->render();
    this->screen.Display();
}


Dies wird in der main.cpp genutz die so aussieht:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{

    while (app.run)
    {
        app.input();

        app.logic();

        app.render();
    }

    return 0;
}


Bitte, Hilfe.

Grüße,
Môr

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

2

04.02.2010, 22:52

wo lädst du denn das image?

C-/C++-Quelltext

1
//imgm.Destroy("img/logo.png"); Lösche ich das Bild manuell erscheint die Verletzung nicht. 


"sorgfältig" ist was anderes. du hast nichtmal private datenelemente in der klasse.
warum schreibst du vor jeder funktion "this->"? das kannst du dir sparen.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

3

04.02.2010, 22:56

Ich kann ja auch keine privaten Datenelemente gebrauchen. Und nur welche zu deklarieren um sie zu deklarieren finde ich zweckentfremdent.

Stimmt, habe ich vergessen zu zeigen.

Intro.hpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef INTRO_HPP
#define INTRO_HPP

#include <SFML/Graphics.hpp>
#include "GameState.hpp"

class Intro :
    public GameState
{
private:
    sf::Sprite logo;
    sf::String copyright;
public:
    Intro();
    ~Intro();

    void input();
    void logic();
    void render();
};

#endif


Intro.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "Intro.hpp"
#include "const.hpp"
#include "global.hpp"
#include "enum.hpp"

Intro::Intro()
{
    app.imgm.Load("img/logo.png");
    logo.SetImage(app.imgm["img/logo.png"]);
    logo.SetX(SCREEN_WIDTH/2-logo.GetSize().x/2);
    logo.SetY(20);

    copyright.SetText("Shane Grüling 2010");
    copyright.SetX(SCREEN_WIDTH-copyright.GetRect().GetWidth());
    copyright.SetY(SCREEN_HEIGHT-copyright.GetRect().GetHeight());
}

Intro::~Intro()
{
}

void Intro::input()
{
    sf::Event Event;
    while (app.screen.GetEvent(Event))
    {
        // Window closed

        if (Event.Type == sf::Event::Closed)
            app.gsm.nextState = STATE_EXIT;

        // Any key pressed

        if (Event.Type == sf::Event::KeyPressed)
            app.gsm.nextState = STATE_MENU;
    }
}

void Intro::logic()
{

}

void Intro::render()
{
    app.screen.Draw(logo);
    app.screen.Draw(copyright);
}


Zum this->: Angewohnheit aus PHP. Bringt allerdings keinen um wenn ich es schreib oder?

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

4

04.02.2010, 23:32

Zitat von »"Môr"«

Ich kann ja auch keine privaten Datenelemente gebrauchen. Und nur welche zu deklarieren um sie zu deklarieren finde ich zweckentfremdent.

ehm... es sollten allgemein ALLE datenelemente als private deklariert werden. sogar protected ist in den meisten fällen nicht kein guter programmierstil.

Zitat

Zum this->: Angewohnheit aus PHP. Bringt allerdings keinen um wenn ich es schreib oder?

nee es verwirrt nur und macht die sache etwas unübersichtlicher.

ich hab mir den sourcecode von dem resourcenmanager angesehen. wenn du ncihts geänder hast und auch wirklich den verlinkten verwendest hab ich kA was sein könnte.

liegt app im globalen bereich mit als public deklarierten, nicht konstanten datenelementen? das ist ne 1a fehlerquelle ;)
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

5

04.02.2010, 23:37

Zitat von »"NachoMan"«

Zitat von »"Môr"«

Ich kann ja auch keine privaten Datenelemente gebrauchen. Und nur welche zu deklarieren um sie zu deklarieren finde ich zweckentfremdent.

ehm... es sollten allgemein ALLE datenelemente als private deklariert werden. sogar protected ist in den meisten fällen nicht kein guter programmierstil.


Okay. Also Get-Methoden schreiben. Macht das ganze natürlich sicherer.

Zitat von »"NachoMan"«


Zitat

Zum this->: Angewohnheit aus PHP. Bringt allerdings keinen um wenn ich es schreib oder?

nee es verwirrt nur und macht die sache etwas unübersichtlicher.


Bei mir ist es genau das Gegenteil. :D

Zitat von »"NachoMan"«


ich hab mir den sourcecode von dem resourcenmanager angesehen. wenn du ncihts geänder hast und auch wirklich den verlinkten verwendest hab ich kA was sein könnte.

liegt app im globalen bereich mit als public deklarierten, nicht konstanten datenelementen? das ist ne 1a fehlerquelle ;)


Habe nichts geändert und verwende auch genau den.
Die global.hpp enthält dies:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
#ifndef GLOBAL_HPP
#define GLOBAL_HPP

#include "Application.hpp"

extern Application app;

#endif


Ich sitze seit Anfang der Woche an dem Problem und weiss einfach nciht was ich falsch mache. Wäre kewl wenn es jmd. findet.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

04.02.2010, 23:39

Schau dir doch einfach mal den Callstack an wenn du die "heap corruption" angezeigt bekommst...

7

04.02.2010, 23:43

Habe ich bereits tausend mal getan.

Zitat

BBAW.exe!std::allocator<std::_Tree_nod<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,sf::Image,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,sf::Image> >,0> >::_Node>::deallocate(std::_Tree_nod<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,sf::Image,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,sf::Image> >,0> >::_Node * _Ptr=0x00325108, unsigned int __formal=1) Zeile 140 + 0x9 Bytes C++
> BBAW.exe!std::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,sf::Image,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,sf::Image> >,0> >::_Tidy() Zeile 1426 C++
BBAW.exe!std::_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,sf::Image,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,sf::Image> >,0> >::~_Tree<std::_Tmap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,sf::Image,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,sf::Image> >,0> >() Zeile 541 C++
BBAW.exe!std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,sf::Image,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,sf::Image> > >::~map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,sf::Image,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,sf::Image> > >() + 0x2b Bytes C++
BBAW.exe!sftools::ResourceManager<sf::Image,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >::~ResourceManager<sf::Image,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > >() Zeile 75 + 0x12 Bytes C++
BBAW.exe!sftools::ImageManager::~ImageManager() + 0x2b Bytes C++
BBAW.exe!Application::~Application() Zeile 14 + 0x20 Bytes C++
BBAW.exe!`dynamic atexit destructor for 'app''() + 0x28 Bytes C++
msvcr90d.dll!6a8bbd05()
msvcr90d.dll!6a8bb9e2()
BBAW.exe!__tmainCRTStartup() Zeile 599 C
BBAW.exe!mainCRTStartup() Zeile 403 C


Wenn du etwas siehst, das ich nciht sehe. Verrat es mir bitte. Ich bin mir ja im klaren das ich einen Fehler gemacht habe, aber ich weiss nicht welchen.

8

04.02.2010, 23:46

Versuch es mal ohne globale Variablen. Kann nämlich sein, dass SFML da Dinge aufräumt, auf welche du später noch zugreifst.

9

05.02.2010, 00:01

App ist jetzt in main() definiert und das Bild wird in Applikation geladen und gezeichnet. Also Intro komplett raus.

Siehe da, Heap Verletzung verschwunden.

Das meintest du doch Nexus, oder?

Einer dann nen Tipp wie ich das klüger lösen kann? Will ja nicht nur in Application Bilder laden können.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

10

05.02.2010, 08:59

nexus war nicht der erste der dich darauf aufmerksam machen wollte. <.<
bau dir ne extra klasse die alle resourcen im konstruktor läd als singleton. bau es so auf, dass man die sounds per enum aufrufen kann.
das hat man in ein paar minuten geschrieben und wenn du die klasse auch noch mit intelligenten zeigern ausstattest, dann brauchst du auch keinen resourcenmanager der mit langsamen strings arbeitet mehr. xD
solltest du vor haben mal eine skriptsprache zu nutzen musst du natürlich ein bisschen umbauen.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Werbeanzeige