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

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

1

05.07.2014, 23:53

C++ seltsames Verhalten eines Pointers

Nabend,

Meine Klasse "UI" hat eine std::map<std::string, TextButton*> TextButtons. TextButton ist eine von mir erstellte Klasse, welche logischerweise ein Button ist, auf dem etwas steht (ähnlich dem "Absenden" oder "Antworten" Button hier im Forum). Die TextButton-Pointer zeigen auf TextButton Objekte, welche sich in der Klasse UI-Container befinden. Mit folgender Art kann man dann auf einen Button zugreifen Gui.GetTextButton("BTNGOLD")->ChangeText("Geld:" + std::to_string(Geld));. Leider funktioniert genau diese Methode NICHT.

Methode ist wie folgt aufgebaut:

C-/C++-Quelltext

1
2
3
4
5
void TextButton::ChangeText(const std::string text)
{
    //Text.setString(text); (Zum testen auskommentiert)
    Text.setString("Gold");
}


Wird diese Methode aufgerufen, bekomme ich die Fehlermeldung, welche auf dem Bild zu sehen ist.
Interessant ist, dass meine "ImageButtons", welche genauso funktionieren einwandfrei funktionieren.

Liegt das nun an meiner Programmierung oder an einem Problem der SFML bei .setString()?


Ich benutze:
Win 8.1, VS 2013, SFML 2.1
»ERROR« hat folgendes Bild angehängt:
  • error.PNG

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »ERROR« (06.07.2014, 00:01)


eXpl0it3r

Treue Seele

Beiträge: 386

Wohnort: Schweiz

Beruf: Professional Software Engineer

  • Private Nachricht senden

2

06.07.2014, 00:57

Debugger anwerfen und mal schauen ob alle Variabeln existieren. Dann Schritt für Schritt durch gehen und schauen wo genau es denn crasht.

Unbedingt auch überprüfen, dass du a) SFML für VS 2013 selbst kompiliert hast (oder meine Nightly Builds verwendest) und dass du nicht Release und Debug mixst.
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/

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

3

06.07.2014, 01:00

Und insbesondere im Debugger gucken ob this in dieser Methode auf etwas sinnvolles zeigt ...
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

4

06.07.2014, 01:22

Doofe Sache, Die Position des Buttons its 0|0 und ich habe einfach nur die überprüft, aber alle Werte sind 0...

Folgender Weise erstelle ich die map:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
[Code irgendwo im Programm:]
    //TOP Container
    cont = RectangleContainer(0, 0, Screen_x, 20, rsc_mgr.GetTexture("TOPMENU"));
    Container.push_back(cont);
    TextButtons["BTNGOLD"] = Container.at(0).AddButton(TextButton(sf::Vector2f(0, 0), sf::Vector2f(50, 20), BtnBuyTower, "STD", "Gold:100", rsc_mgr.Font, 16, sf::Color(0, 0, 0), sf::Color(0, 0, 0, 0)));

[oben aufgerufene Funktion:]
TextButton* RectangleContainer::AddButton(TextButton btn)
{
    TextButtons.push_back(btn);
    return &TextButtons.at(TextButtons.size() - 1);
}

Bitte beachten: TextButtons ist in den beiden Code Teilen jeweils ein anderer Container! Der obere ist die map mit den Zeigern und der untere ist ein vector in dem die tatächlichen Objekte liegen.


Der obrige Code sorgt dafür, dass am Ende in der map (TextButtons) der Zeiger abgelegt wird oder irre ich mich ?

5

06.07.2014, 01:34

Iterator validity
If a reallocation happens, all iterators, pointers and references related to the container are invalidated.
Otherwise, only the end iterator is invalidated, and all iterators, pointers and references to elements are guaranteed to keep referring to the same elements they were referring to before the call.

Dein Zeiger, der von at geliefert wird, ist beim nächsten realloc Schrott.
"Theory is when you know something, but it doesn’t work. Practice is when something works, but you don’t know why. Programmers combine theory and practice: Nothing works and they don’t know why." - Anon

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

6

06.07.2014, 01:39

Ich muss also erst den vector befüllen und danach erst die maps mit den pointern befüllen?

Tobiking

1x Rätselkönig

  • Private Nachricht senden

7

06.07.2014, 08:32

Ich muss also erst den vector befüllen und danach erst die maps mit den pointern befüllen?

Zum einen das, und wenn du später noch Buttons hinzufügst können die Pointer wieder ungültig werden. Eine std::list wäre an der Stelle eher geeignet, da diese kein realloc macht.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

06.07.2014, 08:37

Wahlweise auch eine andere Architektur. Wieso hat eine UI-Klasse eine Map mit Pointern auf Elemente, die in einer anderen Klasse (dem UIContainer) verwaltet werden? Es ist doch offensichtlich, dass sich hier zwei Klassen um die Verwaltung streiten.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

9

06.07.2014, 09:40

Danke Tobiking für den Hinweis mit dem anderen Container :)

@BlueCobold:
Ich wollte es so machen, dass in der GameLoop für das gesame UI nur die Klasse UI bekannt ist, damit diese dann schnell Zugriff auf alle Buttons hat, bekommt sie die Pointer auf alle Buttons. Da die Buttons sowohl logisch als auch "physisch" in den UIContainern sind, wollte ich die Objekte der Buttons auch in den UIContainern speichern. Das macht auch die Maus Kollision mit den UIContainern und dann mit den Buttons in denen einfacher und schneller. Und andere Programmierer oder Leute, die diese Schnittstelle benutzen, sollten sowieso nur Zugriff auf die Klasse UI bekommen.

Ich weiss nicht ob das klar wird, mit den UIContainern baue ich das gesamte Interface auf. Ein Container wäre halt zB eine Leiste am oberen Bildschirm oder das Baumenü recht wie bei so ziemlich jedem Strategie Spiel.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

06.07.2014, 10:17

Trotzdem keine schöne Lösung. Wie gesagt gibt es da eine Redundanz, die offensichtlich in gewissen Fällen zu Fehlern führt. Bei Dir ist es sogar so schlimm, dass die Klasse UI nicht mehr funktioniert, wenn UIContainer seine interne Verwaltung der Objekte ändert. Damit muss UI interne Details vom UIContainer kennen und ist sehr stark von diesen abhängig. Das ist sehr schlecht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige