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

21

28.08.2010, 11:31

Guten Morgen,


Schreibt mein Story nicht mit einem r?

MfG Stazer

Ja, schreib man, hat mich Harry222 schon hingewiesen ... werde es auch ändern, wenn alles funktioniert ;)


Hallo Ombalat,

deine zweite Variante (mit Stack) kann nicht funktionieren, da du einen Pointer auf dieses Sprite zurückgibst, der mit dem Funktionsende ungültig wird - weil ja das Sprite am Ende der Funktion gelöscht wird.
Daher kommt die Zugriffsverletzung.

Du hast das Sprite ja selbst mit "Temporäres Sprite" kommentiert. Dann soll es ja auch nur temporär - also innerhalb der Funktion - zur Verfügung stehen. Danach kannst du nicht mehr drauf zugreifen.
Also entweder du gibst keinen Zeiger, sondern das Objekt selbst zurück oder aber du legst das Sprite auf dem Heap an - dann aber nach Möglichkeit nicht in der Funktion selbst sondern im Konstruktor von CGame und rufst hier nur die Funktion Load() auf.


Gruß
SaRu_


Danke dir.
Hab die Variante mim Stack jetz geändert und liefere das Objekt, und nicht einen Pointer zurück, jedoch habe ich wieder die Zugriffsverletzung :|

C-/C++-Quelltext

1
2
3
Funktionsaufruf:

*pSpriteIntro_Text = LoadStorry(ID_Storry); //Storry Datei laden

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
Funktion:

//Funktion zum Laden der Storry
CSprite CGame::LoadStorry(const int &ID_Storry)
{
    CSprite TempSprite; //Temporäres CSprite für den Text
    if(ID_Storry == 1)
        TempSprite.Load("Data/Emphasis/Storry/Storry_1.Emphasis");
    else if(ID_Storry == 2)
        TempSprite.Load("Data/Emphasis/Storry/Storry_2.Emphasis");
    
    return TempSprite;
}

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Überladener Operator in Sprite (unverändert):

CSprite& CSprite::operator =(CSprite& rhs)
{
    if(m_pImage != NULL)
    {
        SDL_FreeSurface(m_pImage);
        //m_pImage = new SDL_Surface;
    }

    Load(rhs.GetPath());

    return *this;
}


Liebe Grüße,
Ombalat

22

28.08.2010, 12:29

Hallo Ombalat,

du versuchst das zurückgegebene Objekt deiner CSprite Klasse an der Stelle zu speichern, auf die dein Zeiger pSpriteIntro_Text zeigt. Das ist so nicht machbar. Eigentlich solltest du eine solche Warnung beim kompilieren erhalten: "warning C4700: Die nicht initialisierte lokale Variable "pSpriteIntro_text" wurde verwendet." Außer du setzt den Zeiger NULL, aber auch dann funktioniert es nicht.

Das hier sollte funktionieren, allerdings legst du dabei das Objekt wieder auf dem Heap an und kannst die zweite Variante der Funktion (siehe mein vorheriger Post) nehmen.

C-/C++-Quelltext

1
2
CSprite *pSpriteIntro_Text = new CSprite;
*pSpriteIntro_Text = LoadStorry(ID_Storry);


Günstiger wäre in diesem Fall (mit Heap):

C-/C++-Quelltext

1
2
3
4
CSprite *pSpriteIntro_Text = new CSprite;
pSpriteIntro_Text = LoadStorry(ID_Storry); // Wobei dann LoadStorry() wieder einen Zeiger zurückgeben müsste - das hatten wir ja schon... 
//...
// pSpriteIntro_Text steht auch übers Funktionsende hinaus noch zur Verfügung - muss aber, sobald nicht mehr benötigt, mit delete freigegeben werden


Oder nochmal ohne Heap:

C-/C++-Quelltext

1
2
3
4
CSprite SpriteIntro_Text; // Kein Zeiger!
SpriteIntro_Text = LoadStorry(ID_Storry);
//...
// Ende der Funktion -> SpriteIntro_Text wird automatisch freigegeben - steht also nicht mehr zur Verfügung



Ich denke mal, dass du pSpriteIntro_Text auch noch in anderen Funktionen deiner CGame Klasse benötigst (z.B. in Render() oder sowas). Dann solltest du das Objekt auf dem Heap anlegen. Andernfalls - wenns wirklich nur temporär gebraucht wird, dann auf dem Stack. Ist allerdings nur bis zum Funktionsende gültig.

Gruß
SaRu_

23

28.08.2010, 17:48

Guten Abend,

Ich werd das ganze vermutlich lokal am Stack machen ... Wenn ichs mir so überlege, bruach ich das alles nur lokal ;)

Vielen Dank :)
Meld mich nochmal, wenns funktionieren sollte oder ich wieder ein problem habe ;)

Liebe Grüße
Ombalat

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

24

28.08.2010, 18:36

Schreibt mein Story nicht mit einem r?

MfG Stazer

Guck mal weiter oben! ;)

Mfg Harry222

25

28.08.2010, 19:26





Zitat von »Stazer«



Schreibt mein Story nicht mit einem r?

MfG Stazer

Guck mal weiter oben! ;)

Mfg Harry222


Hab ich ihm auch schon gesagt ;)

26

28.08.2010, 21:56

Guten Abend.

Ich habe es jetzt versucht, die Variable lokal auf dem Stack zu erzeugen.
Bekomme jedoch immer noch eine Zugriffsverletztung.

Hier der geänderte Code:

C-/C++-Quelltext

1
2
3
4
5
6
Funktionsaufruf:

    CSprite SpriteIntro_Text; 
    SpriteIntro_Text = LoadStory(ID_Story); //Storry Datei laden
    //pSpriteIntro_Text -> Load("Data/Emphasis/Storry/Storry_2.Emphasis");
    SpriteIntro_Text.SetColourKey(205,179,139);

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
Ladefunktion:

CSprite CGame::LoadStory(const int ID_Story)
{
    CSprite TempSprite; //Temporäres CSprite für den Text
    if(ID_Story == 1)
        TempSprite.Load("Data/Emphasis/Storry/Storry_1.Emphasis");
    else if(ID_Story == 2)
        TempSprite.Load("Data/Emphasis/Storry/Storry_2.Emphasis");
    
    return TempSprite;
}

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
Operator:

CSprite& CSprite::operator =(CSprite& rhs)
{
    if(m_pImage != NULL)
        SDL_FreeSurface(m_pImage);

    Load(rhs.GetPath());

    return *this;
}


Ich bin ziemlich ratlos, wo der fehler liegen könnte, hoffe, ihr hönnt mir wieder weiterhelfen :)

Schönen Abend noch,
Ombalat

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

27

29.08.2010, 15:10





Zitat von »Stazer«



Schreibt mein Story nicht mit einem r?

MfG Stazer

Guck mal weiter oben! ;)

Mfg Harry222


Hab ich ihm auch schon gesagt ;)


Ups! ^^ :whistling:

Mfg Harry222

28

29.08.2010, 17:17

Also nur eine Bemerkung am Rande: Fullquotes sind nicht besonders gern gesehen, also bitte - wenn überhaupt - nur die Textstellen zitieren, auf die ihr euch bezieht. Das ist sonst echt unangenehm zu lesen und macht die Seite nur länger als notwendig. ;)

@Ombalat:

Eins schon mal vorweg, is mir nämlich gerade aufgefallen. Bei deinem Operator kannst du dir das if-Statement sparen. SDL_FreeSurface() einen NULL-Zeiger zu übergeben ist sicher - in diesem Fall passiert einfach gar nichts.

Dein Quellcode sollte eigentlich funktionieren, wo taucht denn die Zugriffsverletzung auf? Immer noch beim SetColourKey()?
Prüf doch mal nach LoadStory() ob SpriteIntro_Text NULL ist.

Was machst du denn mit dem Sprite im weiteren Verlauf deines Prorgamms? Du renderst das Sprite doch mit Sicherheit oder? Und das machst du dann auch in einer anderen Funktion von CGame oder? Dann "musst" du das Objekt eh auf dem Heap anlegen.

Gruß
SaRu_

jokester

Treue Seele

Beiträge: 125

Wohnort: Mainz

  • Private Nachricht senden

29

29.08.2010, 17:19

Der Kopierkonstruktor fehlt noch. Und der Zuweisungsoperator sollte eine const-referenz nehmen.
"There is a theory which states that if ever anyone discovers exactly what the Universe is for and why it is here, it will instantly disappear and be replaced by something even more bizarre and inexplicable. There is another theory which states that this has already happened" -- Douglas Adams.

30

29.08.2010, 17:30

Und der Zuweisungsoperator sollte eine const-referenz nehmen.
Das hatten wir schon weiter oben im Thread .

Gruß
SaRu_

Werbeanzeige