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

27.08.2010, 15:38

Zugriffsverletzung beim Setzten der Colour - Keys

Hallo, ich binns mal wieder.

Ich hab ein Problem, wo ich sicher einen simplen Denkfehler mache ...
Und zwar geht es dabei darum, dass ich einen Pointer habe, den ich über eine Funktion per Return definiere.
Allerdingst bekomme ich nach der Funktion einen Zugriffsfehler, wenn ich versuche den Coulour - Key einzugeben.

Hier mal ein Codeausschnitt:

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
void CGame::CheckFinish(bool *p_bCancelPause)
{
         ...

    //Geschichte Rendern
    if(m_Level == 5)
    {
        RenderStorry(2);
    }

        ...
}

void CGame::RenderStorry(const int &ID_Storry)
{
          ...

          CSprite *pSpriteIntro_Text = new CSprite; 

          pSpriteIntro_Text = LoadStorry(ID_Storry); //Storry Datei laden
         //pSpriteIntro_Text -> Load("Data/Emphasis/Storry/Storry_2.Emphasis"); //So würde es funktionieren (statt der oberen zeile)
         pSpriteIntro_Text -> SetColourKey(205,179,139); //Hier bekomme ich die Zugriffsverletztung

         ...
}

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;
}


Hoffe, ihr könnt mir helfen.

Schönen Abend noch und liebe Grüße,
Ombalat

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

2

27.08.2010, 15:48

//pSpriteIntro_Text -> Load("Data/Emphasis/Storry/Storry_2.Emphasis"); //So würde es funktionieren (statt der oberen zeile)

Warum machst du es dann nicht so?

Hat die CSprite Klasse den einen =-Operator?

Mfg Harry222

3

27.08.2010, 15:53

*Hand auf die Stirn klatsch*
Nein, hat sie natürlich nicht - daran hab ich nicht gedacht.
Vielen Dank für deine Hilfe !



Zitat von »Ombalat«



//pSpriteIntro_Text -> Load("Data/Emphasis/Storry/Storry_2.Emphasis"); //So würde es funktionieren (statt der oberen zeile)


Warum machst du es dann nicht so?


Ich mache es nicht so, weil ich es übersichtlicher finde, wenn ich die Pfadangaben in einer eigenen Funktion stehen habe.
Es steht ja noch mehr in der Funktion drinnen, wo ich LoadStorry() aufrufe ;)
Und es ist so auch freundlicher zum ändern und Hinzufügen für neue Datein, da es nicht nur 2 Bleiben werden ;)

Vielen Dank nocheinmal
Ombalat

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

4

27.08.2010, 16:01

Wo du recht hast, hast du recht!

Und für die Hilfe: Bitte! ^^

Wird es übrigens nicht eigentlich Story und nicht Storry geschrieben? :huh:

Mfg Harry222

5

27.08.2010, 16:33

Hey, hallo nocheinmal :)

Du, das kann ganz gut sein, dass man´s so schreibt ... ich und die doppelkonsonannten ;)

Naja, jedenfalls schaff ichs iwie nicht, den = - Operator zu überladen ....
Hier mal n paar ausschnitte, bitte schaut euch das mal an :huh:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
Sprite.hpp:

public:
    CSprite();
    void Load(const string sFilename);
    void operator = (CSprite *rhs); //Überladen des = Operators

private:
    SDL_Surface *m_pImage; // Das Surface für das Bild, in dem sich das zu rendernde Bild befindet
    string sPath; //Der Pfad, wo die Bilddatei liegt
    string GetPath() { return (sPath); }


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
CSprite.cpp:

CSprite::CSprite()
{
    m_pImage = NULL;
    m_pScreen = g_pFramework -> GetSurface();
}

//Load - Funktion.
//Ermöglicht das Laden eines nicht animierten Sprites
void CSprite::Load(const string sFilename)
{
    m_pImage = SDL_LoadBMP(sFilename.c_str()); //BMP laden
    sPath = sFilename;

    //Fehlerabfrage
    if (m_pImage == NULL)
    {
        cout << "Fehler beim Laden von: " << sFilename.c_str() << endl;
        cout << "Fehlermeldung: " << SDL_GetError() << endl;

        //Framework herunterfahren
        g_pFramework -> Quit();
        //Gesammtes Programm herunterfahren
        exit(1);
    }

    //Rect initialisieren
    m_Rect.x = 0; //X - Pos für die linke obere Ecke im Rect
    m_Rect.y = 0; //Y - Pos für die linke obere Ecke im Rect
    m_Rect.w = m_pImage -> w; //Breite des Rect
    m_Rect.h = m_pImage -> h; //Höhe des Rect
}

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

    Load(rhs -> GetPath());
}


Liebe Grüße

Edit: Habe es auch schon komplett ohne dem Löschenversucht. Bekomme trotzdem immer die Zugriffsverletzung

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Ombalat« (27.08.2010, 16:51)


Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

6

27.08.2010, 17:54

Hast du denn irgendwo auch folgende Codezeile?

C-/C++-Quelltext

1
m_pImage = new SDL_Surface


Mfg Harry222

7

27.08.2010, 17:58

Hallo Ombalat,

probier es doch mal wie folgt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
// Deklaration
public:
CSprite& operator = (const CSprite& Src);

// Implementation
CSprite& CSprite::operator = (const CSprite& Src)
{
 // Hier dein Code...

 return *this; // Referenz auf sich selbst zurückgeben
}


Du solltest (oder musst) zum einen schon mal eine Referenz auf das aktuelle Objekt zurückgeben. Dies geschieht mit return *this.
Außerdem solltest du dem Operator auch eine Referenz übergeben. Zeiger sollte man eher benutzen, wenn du das übergebene Objekt verändern möchtest. Hier bietet sich also eher eine Referenz an. Zudem solltest mit dem Schlüsselwörtchen const arbeiten, zeigt an, dass die Übergebene Instanz von CSprite nicht verändert wird.

Gruß
SaRu_

@Harry222:
SDL_LoadBMP in der SDL Wiki
Returns the new surface or NULL if there was an error

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

8

27.08.2010, 18:13

Ups, hab ich wohl übersehen! ^^

Aber deine Idee müsste funktionieren! :thumbsup:

Mfg Harry222

9

27.08.2010, 18:14

Hallo,

Vielen Dank für die Antworten!
Der Grund, warum ich es ohne Referenz machen wollte, ist, dass ich sonst folgende Fehlermeldung bekomme:

C-/C++-Quelltext

1
2
c:\dokumente und einstellungen\johannes\eigene dateien\spieleprogrammierung\projekte\way light\way light\sprite.cpp(114) : error C2662: 'CSprite::GetPath': this-Zeiger kann nicht von 'const CSprite' in 'CSprite &' konvertiert werden
        Durch die Konvertierung gehen Qualifizierer verloren


Hier der aktualisierte Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
Sprite.hpp:

public:
    CSprite();
    void Load(const string sFilename);
    CSprite &operator = (const CSprite& rhs); //Überladen des = Operators

private:
    SDL_Surface *m_pImage; // Das Surface für das Bild, in dem sich das zu rendernde Bild befindet
    string sPath; //Der Pfad, wo die Bilddatei liegt
    string GetPath() { return (sPath); }


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
Sprite.cpp:

CSprite::CSprite()
{
    m_pImage = NULL;
    m_pScreen = g_pFramework -> GetSurface();
}

//Load - Funktion.
//Ermöglicht das Laden eines nicht animierten Sprites
void CSprite::Load(const string sFilename)
{
    m_pImage = SDL_LoadBMP(sFilename.c_str()); //BMP laden
    sPath = sFilename;

    //Fehlerabfrage
    if (m_pImage == NULL)
    {
        cout << "Fehler beim Laden von: " << sFilename.c_str() << endl;
        cout << "Fehlermeldung: " << SDL_GetError() << endl;

        //Framework herunterfahren
        g_pFramework -> Quit();
        //Gesammtes Programm herunterfahren
        exit(1);
    }

    //Rect initialisieren
    m_Rect.x = 0; //X - Pos für die linke obere Ecke im Rect
    m_Rect.y = 0; //Y - Pos für die linke obere Ecke im Rect
    m_Rect.w = m_pImage -> w; //Breite des Rect
    m_Rect.h = m_pImage -> h; //Höhe des Rect
}

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

    Load(rhs.GetPath());

    return *this;
}


Aber wieso ich den this Zeiger verwenden soll ist mir nicht ganz klar?
Vielleicht verwechsle ich das ja auch gerade, aber die Rechenoperation wird doch von der Instanz links vom "=" aufgerufen und das was rechts im "=" steht ist das, was in der klamer steht (CSprite& CSprite::operator =(const CSprite& rhs)).
Also was bringt es mir dann, wenn ich noch dazu die Instanz zurückliefere, die ich sowieso neu laden tue?

Freundliche Grüße

Harry222

Alter Hase

Beiträge: 864

Beruf: Student

  • Private Nachricht senden

10

27.08.2010, 18:16

Stimmt, da hast du irgendwie recht! Der return würde Sinn machen, wenn es sich z.B. um +,-,* oder / handeln würde! :huh:

Mfg Harry222

Werbeanzeige