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

20.08.2016, 14:46

Selbst erstelltes SFML-Framework produziert Speicherfehler

Hallo,
ich bin gerade dabei mir ein Framework für SFML zu machen um Gamestates und simple Gui Elemente zu erstellen. Allerdings stürzt das Programm beim Start oft mit Speicherfehlern ab. Allerdings nicht immer. Beim Beenden bekomme ich auch Speicherfehler. Ich werde mal den Code posten, da ich relativ neu bei C++ bin und mein Debugger nicht funktioniert. Ich hoffe ihr könnt mir ein paar Tipps geben, bin schon ziemlich verzweifelt.

main.cpp:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "Framework.hpp"

/*
 * 
 */
int main()
{
    CFramework Game(800, 600, "SFML Test", CFramework::Default);
    Game.setState(CFramework::MainMenue);
        
    while(Game.isRunning() == true)
    {
        Game.Run();
    }
    
    return 0;
}


Framework.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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#ifndef FRAMEWORK_HPP
#define FRAMEWORK_HPP

#include <iostream>
#include <string>
#include "SFML/Graphics.hpp"

#include "Button.hpp"
#include "State.hpp"

class CState;

class CFramework
{
private:
    
    CState *m_CurrentState;
    
    //Temp
    sf::Time m_LastFrame;
    
public:
    
    //Variablen
    bool m_Running;
    sf::RenderWindow m_Window;
    enum Style{Default, Close, Titlebar, Resize, Fullscreen, None};
    enum State{MainMenue};
    sf::Clock m_Clock;
    float m_Fps;
    
    //Methoden
    CFramework(int ScreenWidth, int ScreenHeight, std::string WindowTitle, Style WindowStyle);
    ~CFramework();
    
    void Run();
    bool isRunning();
    void setState(State State);
};

#endif /* FRAMEWORK_HPP */


Framework.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
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "Framework.hpp"
#include "MainMenueState.hpp"

//Konstruktor
//
//Initialisiert Fenstergröße, Fenstertitel und Fensterstil
//
CFramework::CFramework(int ScreenWidth, int ScreenHeight, std::string WindowTitle, Style WindowStyle)
{
    switch(WindowStyle)
    {
        case Default:
            
            m_Window.create(sf::VideoMode(ScreenWidth, ScreenHeight), WindowTitle, sf::Style::Default);
            break;
            
        case Resize:
            
            m_Window.create(sf::VideoMode(ScreenWidth, ScreenHeight), WindowTitle, sf::Style::Resize);
            break;
            
        case Close:
            
            m_Window.create(sf::VideoMode(ScreenWidth, ScreenHeight), WindowTitle, sf::Style::Close);
            break;
            
        case Titlebar:
            
            m_Window.create(sf::VideoMode(ScreenWidth, ScreenHeight), WindowTitle, sf::Style::Titlebar);
            break;
            
        case Fullscreen:
            
            m_Window.create(sf::VideoMode(ScreenWidth, ScreenHeight), WindowTitle, sf::Style::Fullscreen);
            break;
            
        case None:
            
            m_Window.create(sf::VideoMode(ScreenWidth, ScreenHeight), WindowTitle, sf::Style::None);
            break;
            
        default:
            
            throw("Window Style not available");
    }
    
    m_CurrentState = 0;
        
    m_Running = true;
}//Konstruktor

//Destruktor
//
//
//
CFramework::~CFramework()
{
    std::cerr << "Destructor of Framework\n";
}//Destruktor

//isRunning
//
//gibt zurück ob Framework läuft
//
bool CFramework::isRunning()
{
    return m_Running;
}//isRunning

//Run
//
//lässt Framework laufen
//
void CFramework::Run()
{
    m_Clock.restart();
    m_CurrentState->HandleEvents(*this);
    m_Window.clear();
    m_CurrentState->Update(*this);
    m_CurrentState->Draw(*this);
    
    m_Window.display();
    
    //Temp
    m_LastFrame = m_Clock.getElapsedTime();
    m_Fps = m_LastFrame.asSeconds();
    m_Fps = 1 / m_Fps;
}//Run

//setState
//
//setzt einen neuen State
//
void CFramework::setState(State State)
{
    delete m_CurrentState;
    
    switch(State)
    {
        case MainMenue:
            
            m_CurrentState = new CMainMenueState;
            break;
            
        default:
            
            m_CurrentState = new CMainMenueState;
    }
}//setState


State.hpp:

C-/C++-Quelltext

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

#include "Framework.hpp"
#include "Button.hpp"

class CFramework;

class CState
{
public:
    
    virtual ~CState(){};
    
    virtual void Draw(CFramework &Framework) = 0;
    virtual void Update(CFramework &Framework) = 0;
    virtual void HandleEvents(CFramework &Framework) = 0;
};

#endif /* STATE_HPP */


Button.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
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
#ifndef BUTTON_HPP
#define BUTTON_HPP

#include "SFML/Graphics.hpp"
#include "Framework.hpp"
#include <string>
#include <iostream>

class CButton : public sf::Drawable
{
    private:
        
        sf::RectangleShape m_Rectangle;
    
    protected:
        
        //Variables
        //
        float m_ActiveScale;
        float m_PressedScale;
        sf::Color m_MainColor;
        sf::Color m_OutlineColor;
        sf::Color m_ActiveColor;
        sf::Color m_MainTextColor;
        sf::Color m_ActiveTextColor;
        bool m_Pressed;
        bool m_Active;
        sf::Text m_MainText;
        sf::Text m_ActiveText;
        
        //Methods
        //
        virtual void draw(sf::RenderTarget &target, sf::RenderStates states)const;   //Makes the class drawable
        
        public:
            
            //Constructor, Destructor
            CButton();
            //CButton(int xPos, int yPos, int Width, int Height, const std::string &MainText, const sf::Font &Font);
            //CButton(int xPos, int yPos, int Width, int Height, const std::string &MainText, const sf::Font &Font, const sf::Color &MainColor);
            ~CButton();
            
            //Setter
            void setPosition(int xPos, int yPos);
            void setSize(int Width, int Height);
            void setActiveScale(float Scale);
            void setPressedScale(float Scale);
            void setMainColor(const sf::Color &Color);
            void setOutlineColor(const sf::Color &Color);
            void setMainString(const std::string &String);
            void setMainStringColor(const sf::Color &Color);
            void setActiveString(const std::string &String);
            void setActiveStringColor(const sf::Color &Color);
            void setOutlineThickness(float OutlineThickness);
            void setFont(const sf::Font &Font);
            
            //Getter
            int getXPos();
            int getYPos();
            int getWidth();
            int getHeight();
            sf::Color getMainColor();
            sf::Color getOutlineColor();
            float getActiveScale();
            //float getMainScale();
            std::string getMainText();
            std::string getActiveText();
            float getOutlineThickness();
            bool isPressed();
            bool isActive(float MouseXPos, float MouseYPos);
            
            //Methods
            void move(int x, int y);
        
};

#endif /* BUTTON_HPP */


Button.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
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#include "Button.hpp"

//Constructor
//
CButton::CButton()
{
    m_ActiveScale = 1.0f;
    m_PressedScale = 1.0f;
    m_MainColor.White;
    m_ActiveColor.White;
    m_MainText.setString("Button");
    m_MainText.setColor(sf::Color::Black);
    m_MainTextColor.Black;
    m_ActiveTextColor.Black;
    m_ActiveText = m_MainText;
    
    m_Rectangle.setOutlineColor(sf::Color::Black);
    m_Rectangle.setFillColor(sf::Color::White);
    m_Rectangle.setOutlineThickness(1.0f);
    
    m_Active = false;
    m_Pressed = false;
}

/*
//Constructor
//
CButton::CButton(int xPos, int yPos, int Width, int Height, const std::string &MainText, const sf::Font &Font)
{
    m_MainText.setString(MainText);
    m_Rectangle.setSize(sf::Vector2f(Width, Height));
    m_Rectangle.setPosition(static_cast<int> (xPos), static_cast<int> (yPos));
    m_ActiveScale = 1.0f;
    m_PressedScale = 1.0f;
    m_MainColor.White;
    m_ActiveColor.White;
    m_MainTextColor.Black;
    m_ActiveTextColor.Black;
    m_ActiveText = m_MainText;
    m_MainText.setFont(Font);
    
    m_MainText.setPosition(Height, Width);
    m_ActiveText.setPosition(Height, Width);
    
    m_Rectangle.setOutlineColor(sf::Color::Black);
    m_Rectangle.setFillColor(sf::Color::White);
    m_Rectangle.setOutlineThickness(1.0f);
    
    m_Active = false;
    m_Pressed = false;
}//Constructor

//Constructor
//
//sets also the main Color
//
CButton::CButton(int xPos, int yPos, int Width, int Height, const std::string& MainText, const sf::Font& Font, const sf::Color &MainColor)
{
    m_MainText.setString(MainText);
    m_Rectangle.setSize(sf::Vector2f(Width, Height));
    m_Rectangle.setPosition(static_cast<int> (xPos), static_cast<int> (yPos));
    m_ActiveScale = 1.0f;
    m_PressedScale = 1.0f;
    m_MainColor.Black;
    m_ActiveColor.Black;
    m_MainTextColor.White;
    m_ActiveTextColor.White;
    m_ActiveText = m_MainText;
    m_MainText.setFont(Font);
    
    m_MainText.setPosition(Height, Width);
    m_ActiveText.setPosition(Height, Width);
    
    m_Rectangle.setOutlineColor(sf::Color::Black);
    m_Rectangle.setFillColor(MainColor);
    m_Rectangle.setOutlineThickness(1.0f);
    
    m_Active = false;
    m_Pressed = false;
}//Constructor
*/

//Destructor
//
CButton::~CButton()
{
    std::cerr << "Destructor of an instance of CButton\n";
}//Destructor



//setPosition
//
//setsPosition of the Button
//
void CButton::setPosition(int xPos, int yPos)
{
    m_Rectangle.setPosition(static_cast<int>(xPos), static_cast<int>(yPos));
    m_MainText.setPosition(static_cast<int>(xPos), static_cast<int>(yPos));
    m_ActiveText.setPosition(static_cast<int>(xPos), static_cast<int>(yPos));
}//setPosition

//setSize
//
//sets the size (Width and Height) of the Button
//
void CButton::setSize(int Width, int Height)
{
    m_Rectangle.setSize(sf::Vector2f(Width, Height));
}//setSize

//setActiveScale
//
//sets the amount the Buttons size changes when the mousepointer is over it
//
void CButton::setActiveScale(float Scale)
{
    m_ActiveScale = Scale;
}//setActiveScale

//setPressedScale
//
//sets the amount the Buttons size changes when it's pressed(broken)
//
void CButton::setPressedScale(float Scale)
{
    m_PressedScale = Scale;
}//setPressedScale

//setMainColor
//
//sets the Color shown when the Button is inactive
//
void CButton::setMainColor(const sf::Color &Color)
{
    m_MainColor = Color;
}//setMainColor

//setOutlineColor
//
//sets the Color of the Outline
//
void CButton::setOutlineColor(const sf::Color &Color)
{
    m_OutlineColor = Color;
}//setOutlineColor

//setMainString
//
//sets the text shown when the Button is inactive
//
void CButton::setMainString(const std::string &String)
{
    m_MainText.setString(String);
}//setMainString

//setMainStringColor
//
//sets the Color of the text
//
void CButton::setMainStringColor(const sf::Color& Color)
{
    m_MainText.setColor(Color);
}//setMainStringColor

//setActiveString
//
//sets the text shown when the mousepointer is over the Button
//
void CButton::setActiveString(const std::string &String)
{
    m_ActiveText.setString(String);
}//setActiveString

//setActiveStringColor
//
//sets the Color of the text
//
void CButton::setActiveStringColor(const sf::Color &Color)
{
    m_ActiveText.setColor(Color);
}//setActiveColor

//setOutlineThicknes
//
//sets the Thickness of the outline
//
void CButton::setOutlineThickness(float OutlineThickness)
{
    m_Rectangle.setOutlineThickness(OutlineThickness);
}//setOutlineThickness

//setFont
//
//sets the Font of the text shown on the Button
//
void CButton::setFont(const sf::Font &Font)
{
    m_MainText.setFont(Font);
    m_ActiveText.setFont(Font);
}//setFont


//getXPos
//
//returns the X-Position of the Button
//
int CButton::getXPos()
{
    sf::Vector2f Pos = m_Rectangle.getPosition();
    int xPos = static_cast<int>(Pos.x);
    
    return xPos;
}//getXPos

//getYPos
//
//returns the Y-Position of the Button
//
int CButton::getYPos()
{
    sf::Vector2f Pos = m_Rectangle.getPosition();
    int yPos = static_cast<int>(Pos.y);
    
    return yPos;
}//getYPos

//getWidth
//
//returns the Width of the Button
//
int CButton::getWidth()
{
    int Width = static_cast<int> (m_Rectangle.getSize().x);
    
    return Width;
}//getWidth

//getHeight
//
//returns the Height of the Button
//
int CButton::getHeight()
{
    int Height = static_cast<int> (m_Rectangle.getSize().y);
    
    return Height;
}//getHeight

//getMainColor
//
//return the MainColor of the Button
//
sf::Color CButton::getMainColor()
{
    return m_MainColor;
}//getMainColor

//getOutlineColor
//
//returns the OutlineColor of the Button
//
sf::Color CButton::getOutlineColor()
{
    return m_OutlineColor;
}//getOutlineColor

//getActiveScale
//
//returns the amount the Buttons size increases when the mousepointer is over it
//
float CButton::getActiveScale()
{
    return m_ActiveScale;
}//getActiveScale

//getMainText
//
//returns the string, which is displayed when the Button is inactive
//
std::string CButton::getMainText()
{
    return m_MainText.getString();
}//getMainText

//getActiveText
//
//returns the string, which is displayed when the Button is active
//
std::string CButton::getActiveText()
{
    return m_ActiveText.getString();
}//getActiveText

//getOutlineThickness
//
//returns the Thickness of the Outline
//
float CButton::getOutlineThickness()
{
    return m_Rectangle.getOutlineThickness();
}//getOutlineThickness

//isActive
//
//returns true when the Button is active
//
bool CButton::isActive(float MouseXPos, float MouseYPos)
{
    sf::Vector2f MousePos;
    MousePos.x = MouseXPos;
    MousePos.y = MouseYPos;
    
    if(MousePos.x >= m_Rectangle.getPosition().x && MousePos.y >= m_Rectangle.getPosition().y)
    {
        if(MousePos.x <= ((m_Rectangle.getPosition().x) + (m_Rectangle.getSize().x)) && MousePos.y <= ((m_Rectangle.getPosition().y) + (m_Rectangle.getSize().y)))
        {
            m_Active = true;
        }
        else
        {
            m_Active = false;
        }
    }
    else
    {
        m_Active = false;
    }
    
    return m_Active;
    
}//isActive

//isPressed
//
//returns true when the Button is Pressed (Suprise)
//
bool CButton::isPressed()
{
    if(m_Active == true && sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        m_Pressed = true;
    }
    else
    {
        m_Pressed = false;
    }
    
    return m_Pressed;
    
}//isPressed

//move
//
//moves the Button by a specific amount pixel
//
void CButton::move(int x, int y)
{   
    m_Rectangle.move(static_cast<float>(x), static_cast<float>(y));
}//move

//draw(broken)
//
//makes the Button drawable
//
void CButton::draw(sf::RenderTarget &target, sf::RenderStates states)const
{
    target.draw(m_Rectangle, states);  //Draw Rect here
    if(m_Active)
        target.draw(m_ActiveText, states);
    
    else
        target.draw(m_MainText, states);
    
}//draw


Tut mir leid wenn das Ganze vielleicht etwas länger dauert, aber ich kann mir nicht mehr helfen :(
Ich wünsche euch noch einen schönen Tag :)

2

20.08.2016, 14:56

Benutz den Debugger.

MfG
Check

3

20.08.2016, 15:03

Mein Tip: Nutze den Debugger. Setzt am Anfang ein Breakpoint und geh dein Programm Schritt für Schritt durch.

Dann weißt du wo der Fehler auftritt und kannst die Sache schon mal eingrenzen (und dass dann nochmal mitteilen).

Weiterhin solltest du dich mal über Smartpointer informieren und Klassen die sich gegenseitig kennen müssen zeugt von schlechtem Design.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Koschi« (20.08.2016, 19:23)


4

23.08.2016, 16:55

Hallöchen.

Habs mal überflogen. Der Pointer m_CurrentState wird im CFramework Konstruktor auf 0 (schlecht, s.u.) gerichtet.
In der main rufst du anschließend Game.setState() auf. Der erste Befehl in CFRamework::setState() ist "delete m_CurrentState" (wieso?). Ergo will dein Programm Heapspeicher in einem Bereich freigeben auf den m_CurrentState zeigt. Der Pointer zeigt aber auf 0, es wurde kein Heapspeicher mit "new" allokiert.
Boom, Crash.

Bitte lies dir nochmal einige C++ Grundlagen durch. Ebenso die SFML Doc. Du vermischst Klassen miteinander und schreibst Methoden unnötig und umständlich neu, obwohl SFML dir diese schon zur Verfügung stellt.


Gruß
Fanta

PS: Pointer bei Initialisierung mit dem keyword "nullptr" initialisieren. Typsicherheit und C++11 lässt grüßen.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

5

23.08.2016, 17:21

Bitte lies dir nochmal einige C++ Grundlagen durch.

Das gilt aber auch für dich, denn delete mit einem Nullzeiger ist völlig in Ordnung. ;)

Goldwing Studios

Treue Seele

Beiträge: 359

Wohnort: Heidelberg

Beruf: Softwareentwickler, Vertriebler

  • Private Nachricht senden

6

23.08.2016, 18:05

Kannst du den ganzen Code in einzelne Fold-Tags packen?

Erhöht die Übersichtlichkeit und Lesbarkeit ;)

7

24.08.2016, 18:37

Das delete in setState() ist da um den nicht mehr benötigten Heap-Speicher des letzten states freizugeben. Sonst gibt es doch ein Leak, oder? Wüsste nicht wo ich SFML Methoden neu implementiert habe. Habe jetzt die IDE gewechselt und das Programm durch den Debugger gehen lassen. Der crash am Ende kam, da ich in der Update Methode von einem State denselben State mit delete gelöscht habe ihne aber in der Draw Methode danach noch ansprechen wollte. Habe das löschen des States nun in den Destruktor verschoben. Das funktioniert auch:)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

24.08.2016, 22:09

Destruktor von was? CFramework? Dann hättest du da einen Memory-Leak, jedes Mal, wenn du einen neuen State zuweist, weil der alte ja nicht gelöscht wird und stattdessen der Pointer weiter lebt, du ihn nur nirgends mehr zur Hand hast.
Vielleicht ist es stattdessen einfach unklug, dass ein State selbst scheinbar während seines Updates einen anderen State aktivieren kann und sich danach trotzdem selbst zeichnen will? Das ist ja an sich schon ein logisches Problem, weil er ja beim Setzen eines anderen States selbst gelöscht werden müsste, während er sich updated. Über diesen Kontrollfluss solltest du an sich nochmal nachdenken.
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]

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

9

24.08.2016, 22:15

Ich habe das immer so gelöst, dass der State einen Wechsel nur “vormerken“ kann. Der eigentliche Wechsel findet dann anschließend an einer fest definierten Stelle im Main-Loop statt.

10

24.08.2016, 22:31

Tut mir leid, falls ich mich schlecht ausgedrückt habe. Das delete in setState existiert noch. Das muss da auch hin :D Ich hatte vorher eine Funktion, welche das Programm beendet, indem es m_running auf false setzt, das fenster schließt und currentState löscht. Das hatte zurfolge das in der Update Methode der State gelöscht wurde, aber in der Draw Methode nochmal aufgerufen wurde-> Crash. Das habe ich umgangen, indem ich in der Funktion, welche das Programm beendet nur running auf false stelle und der Rest im Destruktor von CFramework gemacht wird. State in einem State wechseln ist kein Problem außer das der erste Frame von einem State nicht geupdated wird. Entschuldigt die Tippfehler, bin am Handy :D

Werbeanzeige