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

spacegaier

Alter Hase

  • »spacegaier« ist der Autor dieses Themas

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

1

02.10.2006, 21:52

Komisches Problem (weiß keinen besseren Titel)

Hallo,

hab folgendes (äußert komisches) Problem:

Ich möchte mittels SDL eine Schrift laden. Dazu lege ich mir in der Headerdatei, einen Zeiger an. In diesen soll dann in der Quellcodedatei über die Funktion TTF_OpenFont der Zeiger auf die zu verwendende Schrift geschrieben werden. Wenn ich nun unten stehenden Code ausführe, bekomme ich bei der Funktion TTF_OpenFont einen Laufzeitfehler:

[list]Unbehandelte Ausnahme bei 0x0040163a in StreetRacer - I.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00000008.[/list]1. (Neben-)Frage: Warum ???

2. (Haupt-)Frage: Wenn ich den Zeiger nicht in der Headerdatei, sondern direkt in der Codedatei erstelle geht es !?! Warum ???

font.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
#ifndef FONT_HPP
#define FONT_HPP 

#include "framework.hpp" 
#include <SDL_ttf.h> 

class CFont
{
public:
    CFont();
    ~CFont();

    void LoadFont(const string sFontname, int iFontsize);

private: 
    SDL_Surface *m_pScreen; 
    SDL_Surface *m_pText;
    TTF_Font *m_pFont;
};

#endif


font.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
#include "font.hpp"
#include "Logfile.hpp"
#include <SDL_ttf.h>

//Konstruktor

CFont::CFont()
{
    m_pScreen = g_pFramework->GetScreen();
    m_pFont = NULL;
}

//Destruktor

CFont::~CFont()
{
    SDL_FreeSurface(m_pText);
}

//LoadFont

void CFont::LoadFont(const string sFilename, int iFontsize)
{
    m_pFont = TTF_OpenFont(sFilename.c_str(),iFontsize);

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

        g_pFramework->Quit();

        exit(1);
    }
}


So bekomme ich keinen Fehler (Frage2):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//LoadFont

void CFont::LoadFont(const string sFilename, int iFontsize)
{
    TTF_Font *m_pFont = TTF_OpenFont(sFilename.c_str(),iFontsize);

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

        g_pFramework->Quit();

        exit(1);
    }
}


Woher rührt dieses komische Problem, oder ist es gar nicht komisch, sondern logisch und ich hab mal wieder was falsch gemacht?

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

2

03.10.2006, 00:30

Dein CFont Objekt, in dem du "LoadFont" aufrufst, wird ein 0-Pointer sein.

PS: für sowas nimmt man den Debugger. :roll:
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

spacegaier

Alter Hase

  • »spacegaier« ist der Autor dieses Themas

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

3

03.10.2006, 08:41

Ja, stimmt, Der Pointer hat noch keine Adresse zugewiesen bekommen (nur NULL). Aber wie löse ich das dann ?

Ich würde gerne folgendes machen:

C-/C++-Quelltext

1
m_pFont = new TTF_Font;


Geht aber nicht, da es keinen passenden Standardkonstruktor für TTF_Font gibt. Und für TTF_OpenFont muss ich einen Zeiger nehmen, da von der Funktion einer zurückgeliefert wird -> normale Variable geht auch nicht :( .

Gibt es irgendweine Möglichkeit, wie ich das sinnvoll (oder überhaupt) lösen könnte?

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

4

03.10.2006, 09:41

Neinneinnein :) das meinte ich doch gar nicht.

Nicht dein m_pFont ist 0 (das wäre egal) sondern das CFont Objekt drumrum ist 0. Also was in dieser Art:

C-/C++-Quelltext

1
2
3
4
CFont pFont = 0;
pFont->LoadFont ("arial.ttf", 12);
/* oder noch brutaler */
reinterpret_cast<CFont*> (0)->LoadFont ("arial.ttf", 12);


Sprich, der Platz, wo der Zeiger m_pFont gespeichert wird liegt selbst schon in einem ungültigen Bereich. Ablesen kann man das an der Fehlermeldung:

Zitat

Zugriffsverletzung beim Schreiben an Position 0x00000008.


Wenn P der Zeiger auf dein CFont Objekt ist, müsste m_pSreen bei P + 0, m_pText bei P + 4 und m_pFont bei P + 8 liegen (warum das so ist, kannst du dir selbst überlegen, das ist eine gute Gedankenübung für Pointer). Mit P = 0 kommen wir genau auf die angemeckerte 8. Voilà.

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Chase

Alter Hase

Beiträge: 753

Wohnort: Nagaoka / Darmstadt / Düsseldorf

Beruf: fauler Studi

  • Private Nachricht senden

5

03.10.2006, 11:19

Und wenn er den Pointer einfach in die cpp in den Namespace der Klasse schreibt wird er statisch oder ?
"Have you tried turning it off and on again?"

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

6

03.10.2006, 12:33

Zitat von »"Chase"«

Und wenn er den Pointer einfach in die cpp in den Namespace der Klasse schreibt wird er statisch oder ?


Nein, wenn er den Pointer in seiner Implementation von LoadFont definiert (in seinem Beispiel, das funktioniert), ist das eine lokale Variable. Das geht immer, auch wenn das Objekt selbst ein 0-Pointer ist.

Das ist das Gemeine an der Sache; solange man in einer Methode keine Member-Variable braucht, funktioniert die Methode auch dann noch korrekt, wenn das Objekt, in dem sie aufgerufen wird, ungültig ist. Solche Methoden kann man daran erkennen, dass sie auch dann noch arbeiten, wenn sie static sein können.

Abgesehen davon will er hier ganz sicher auch gar keine Statics benutzen, weil er dann ja auch nur noch einen Font haben könnte.

MfG,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

spacegaier

Alter Hase

  • »spacegaier« ist der Autor dieses Themas

Beiträge: 572

Beruf: Student

  • Private Nachricht senden

7

03.10.2006, 12:43

Zitat

Abgesehen davon will er hier ganz sicher auch gar keine Statics benutzen, weil er dann ja auch nur noch einen Font haben könnte.

Richtig.

Zu dem CFont-Objekt: Hab es jetzt richtig initialisiert -> es läuft :) .

Das mit dem Gedankenbeispiel kapier ich aber net :( . Könnsch mir das noch bitte erklären?

Danke schonmal für alles!

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

8

03.10.2006, 13:04

Zitat von »"spacegaier"«

Das mit dem Gedankenbeispiel kapier ich aber net :( . Könnsch mir das noch bitte erklären?


Okay, ein kleiner Tip, getarnt als Frage.

C-/C++-Quelltext

1
2
3
4
5
6
7
void CFont::foo ()
{
  if (reinterpret_cast<void**> (this + 8) == &m_pFont)
    std::cerr << "Huch, gleiche Adresse...;)" << std::endl;
  else
    std::cerr << "Rainer redet Unsinn... ;)" << std::endl;
}


Was wird da wohl ausgegeben und warum?

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Sicaine

unregistriert

9

04.10.2006, 16:05

"Bekomme beim Laden einer Schrift mit der SDL eine unbehandelte Ausnahme"

Was is daran so schwer?

Anonymous

unregistriert

10

04.10.2006, 17:04

Zitat von »"Sicaine"«

"Bekomme beim Laden einer Schrift mit der SDL eine unbehandelte Ausnahme"

Was is daran so schwer?


Sie zu behandeln. :lol:

Werbeanzeige