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

Volker_Neff

Treue Seele

  • »Volker_Neff« ist der Autor dieses Themas

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

1

07.09.2015, 17:30

SFGUI bad alloc

Guten Tag,

ich suche nun seit etwa zwei Wochen einen Fehler in meinem Prgramm und komme zunehmend zu der Meinung das er gar nicht bei mit liegt sondern viel mehr in der SFGUI. Ganz kurz zu meinem Problem und dem was ich bis jetzt ausprobiert habe.

Ich habe ein Fester in SFML erstellt und nutze das zum rendern von SFGUI Elementen. Diese sind in bis zu 4 Ebenen über einander angeordnet und werden jedes Frame aktuallisert. Leider bricht das Programm nach einer nicht genauer definierten Zeit ab und das Objekt "this->sfgui.Display(this->render_window);" wirft eine std::bad_alloc exception. Diese wird machmal nach etwa 20min oder aber nach fast 2Std geworfen. Der Versuch konstante Werte über die gesamte Zeit zu rendern liefert den selben Fehler. Wenn ich den Update bereich für das Lable und Progressbar deaktiviere scheint es keine Probleme zu geben, das Progreamm ist mehrmals über 4Std ohne Fehler gelaufen.

Nun meine Frage kennt jemand das Prblem oder hat eine Ahnung was der Fehler sein könnte?

Updatemethode für das Lable und den Progressbar:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
void SongObject::refresh_time_lable()
{
    std::chrono::milliseconds current = this->song.get_time_position();

    this->time_lable->SetText(time_to_string(current, true)/*"00:00:00"*/);

    float fractrion = static_cast<float>(current.count()) / static_cast<float>(this->endtime.count());
    this->time_prgressbar->SetFraction(fractrion/*1.0f*/);
}


und der Funktionsblock der die Exception wirft:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void MainClass::draw()
{
    try
    {
        this->desktop.Update(1.0f); // Time 1 second
        this->render_window.clear(sf::Color{ 50, 50, 50 });
        this->sfgui.Display(this->render_window);
        this->render_window.display();
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }
}


Egal wie ich Konstante einfüge oder versuche das Programm zu vereinfachen. Das einzige was hilft ist die refresh_time_lable() Methode auszukommentieren.

Über Ideen und Anregungen würde ich mich sehr freuen. Vielen Dank schon einmal an euch

Tobiking

1x Rätselkönig

  • Private Nachricht senden

2

07.09.2015, 17:45

Das std:bad_alloc wird von new geschmissen wenn der Speicher nicht reserviert werden kann. Hast du mal geschaut wie sich der Speicherverbrauch deiner Anwendung verhält? Ich würde darauf tippen das du ein Memleak hast. Der muss auch nicht in dem Code sein wo der Fehler auftritt.

Volker_Neff

Treue Seele

  • »Volker_Neff« ist der Autor dieses Themas

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

3

07.09.2015, 17:56

Laut Taskmanager bleibt das recht konstant +/- 200k tendenz ehr sinkend,warum auch immer. Gibt es eine Möglichkeit das noch genauer zu messen?

4

07.09.2015, 18:21

Vielleicht versuchst du einen enorm großen Buffer mit new anzulegen, was schon vornherein ein bad_alloc wirft.
Oder reservierst superviele kleine Buffer, gibst diese dann unregelmäßig frei und wenn du dann einen etwas größeren Buffer haben willst, knallts. Beziehungsweise macht das SFGUI.

Volker_Neff

Treue Seele

  • »Volker_Neff« ist der Autor dieses Themas

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

5

07.09.2015, 18:51

Ja das kann seht gut sein das mir während des Debuggen das Reservieren eines Vectors mit Max int über den weg gelaufen ist. Da ist dann aber immer noch die Frage wo die ganzen Elemente her kommen. Es werden nur diese Beiden Funktionen jeden Frame auf gerufen der Rest bleibt konstant. Ich werde mit das zu hause noch einmal genau angucken und auch noch einmal einen Langzeit test machen. Vielen Dank schon mal für deine Hilfe

Volker_Neff

Treue Seele

  • »Volker_Neff« ist der Autor dieses Themas

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

6

08.09.2015, 17:49

Ich habe noch einmal ne Frage zu dem bad_alloc. Der wird also geworfen wenn es keinen Speicher mehr gibt den new reservieren kann, stimmt das so? Warum stürtzt das Programm dann an einer mehr oder weniger zufälligen Stelle ab. Ich habe versucht das die Testumgebung so sauber wie möglich zu halten, keine Unnötigen eingaben, keine anderen Programme die im Hintergrund laufen.
Der Fehler muss doch eigentlich durch eine der Funktionen kommen die Auskomentiert habe. Wie aber kann ich dort feststellen ob ich ein Speicherleak habe.
benutzt wird noch diese Funktion aber auch dort arbeite ich eigentlich nicht mit etwas was ein Leak hervorrufen sollte:

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
std::string SongObject::time_to_string(std::chrono::milliseconds time, bool mili)
{
    std::stringstream out;
    std::chrono::milliseconds t = time;

    std::chrono::hours hour = std::chrono::duration_cast<std::chrono::hours>(t);
    t -= hour;
    std::chrono::minutes min = std::chrono::duration_cast<std::chrono::minutes>(t);
    t -= min;
    std::chrono::seconds sec = std::chrono::duration_cast<std::chrono::seconds>(t);
    t -= sec;

    if (hour > std::chrono::hours{ 0 })
        out << hour.count() << ":";

    if (min.count() < 10 && hour > std::chrono::hours{ 0 })
        out << "0" << min.count() << ":";
    else
        out << min.count() << ":";

    if (sec.count() < 10)
        out << "0" << sec.count();
    else
        out << sec.count();

    if (hour <= std::chrono::hours{ 0 } && mili)
        out << ":" << static_cast<unsigned int>(t.count() / 100);

    return out.str();
}

7

09.09.2015, 00:22

Lass doch mal valgrind drüberlaufen.

MfG
Check

eXpl0it3r

Treue Seele

Beiträge: 386

Wohnort: Schweiz

Beruf: Professional Software Engineer

  • Private Nachricht senden

8

10.09.2015, 12:09

Ohne ein compilierbares und minimales Beispiel ist die Chance höher, dass es irgendwo an deinem Code liegt. ;)
Blog: https://dev.my-gate.net/
—————————————————————————
SFML: https://www.sfml-dev.org/
Thor: http://www.bromeon.ch/libraries/thor/
SFGUI: https://github.com/TankOs/SFGUI/

Volker_Neff

Treue Seele

  • »Volker_Neff« ist der Autor dieses Themas

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

9

12.09.2015, 16:15

@Checkmateing gibt es so etwas tolles auch für Windows?

@eXpl0it3r das kann ich mir auch sehr gut vorstellen nur ganz verstehen tue ich es nicht. Hatte gehofft es würde da eine einfache Erklärung für geben die ich einfach nur übersehen habe.

Volker_Neff

Treue Seele

  • »Volker_Neff« ist der Autor dieses Themas

Beiträge: 249

Wohnort: Hamburg

  • Private Nachricht senden

10

17.09.2015, 19:32

Nach weiteren tagen debuggen habe ich mich nun daran gesetzt eine kurze Version zu schreiben die nur den Fragwürdigen Teil enthält. Dabei benutze ich nur SFML und SFGUI elemente und sonst gar nichts.
Nach 137081 Frames bricht das Programm mit einem bad_alloc ab.

Ich würde mich freuen wenn einer den Code auch einmal Compilieren und testen könnte ob bei ihm der Selbe Fehler auftritt. Es kann gut sein das es bei euch ein wenig länger brauch der Fehler ist bei mir zwischen 130000 und 160000 Frames auf getreten.
Danke für eure Hilfe

Hier einmal der Code:

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <SFML\Graphics.hpp>
#include <SFGUI\SFGUI.hpp>
#include <SFGUI\Desktop.hpp>
#include <SFGUI\Window.hpp>
#include <SFGUI\Table.hpp>
#include <SFGUI\Button.hpp>
#include <SFGUI\Notebook.hpp>
#include <SFGUI\Box.hpp>
#include <SFGUI\Label.hpp>
#include <SFGUI\Frame.hpp>
#include <SFGUI\ScrolledWindow.hpp>
#include <SFGUI\Renderer.hpp>
#include <SFGUI\ProgressBar.hpp>


int main()
{
    sf::VideoMode video_mode{ 200, 200 };
    sf::RenderWindow window{ video_mode, "Test" };
    window.resetGLStates();
    sfg::SFGUI sfgui;
    sfg::Desktop desktop;
    sf::Event event;


    sfg::Notebook::Ptr notebook = sfg::Notebook::Create();
    sfg::ScrolledWindow::Ptr scroled_window = sfg::ScrolledWindow::Create();
    sfg::Box::Ptr scenebox = sfg::Box::Create(sfg::Box::Orientation::HORIZONTAL);
    sfg::Box::Ptr box = sfg::Box::Create(sfg::Box::Orientation::VERTICAL);
    sfg::Frame::Ptr frame = sfg::Frame::Create(L"Test");
    sfg::Table::Ptr table = sfg::Table::Create();
    sfg::Button::Ptr button = sfg::Button::Create("Test");
    sfg::ProgressBar::Ptr bar = sfg::ProgressBar::Create();

    table->Attach(button, sf::Rect < sf::Uint32 > {0, 0, 2, 1});
    table->Attach(bar, sf::Rect < sf::Uint32 > {1, 1, 1, 1});

    frame->Add(table);
    frame->SetRequisition(sf::Vector2f{ 50.0f, 500.0f });

    box->Pack(frame);
    scenebox->Pack(box);

    scroled_window->SetScrollbarPolicy(sfg::ScrolledWindow::HORIZONTAL_NEVER | sfg::ScrolledWindow::VERTICAL_ALWAYS);
    scroled_window->AddWithViewport(scenebox);
    scroled_window->SetRequisition(sf::Vector2f{ 50.0f, 500.0f });

    notebook->AppendPage(scroled_window, sfg::Label::Create(L"Page 1"));
    notebook->SetRequisition(sf::Vector2f{ 50.0f, 500.0f });

    desktop.Add(notebook);

    size_t frameCount = 0;

    while (window.isOpen())
    {
        while (window.pollEvent(event))
        {
            desktop.HandleEvent(event);
            if (event.type == sf::Event::Closed)
            {
                window.close();
            }
            if (event.type == sf::Event::Resized)
            {
            }
        }
        
        button->SetLabel("Test");
        bar->SetFraction(1.0f);

        desktop.Update(1.0f); // Time 1 second
        window.clear(sf::Color{ 50, 50, 50 });
        sfgui.Display(window);
        window.display();

        frameCount++;
        std::cout << frameCount << std::endl;
    }
}

Werbeanzeige