Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Jul 16, 2025 01:09

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: SDL Timer AccessViolation
BeitragVerfasst: Mo Feb 11, 2008 19:21 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 29, 2005 21:11
Beiträge: 88
Wohnort: Bonn
Moin!

Ich schreibe im Moment eine Konsolenanwendung mit SDL und OpenGL und wollte einen Timer zur Ausgabe der FPS einbauen.
Allerdings schmiert das gesamte Programm mit einer AccessViolation at 0x00000001 read 0x00000001 ab, wenn ich mehr als ein WriteLn in der TimerFunktion verwende.

So sieht sie aus
Code:
  1. function TGame.FPSTimer(Interval: UInt32; param: Pointer): Integer;
  2. var
  3.   event: PSDL_Event;
  4. begin
  5.   WriteLn('FPSTimer');
  6.  
  7.   event.type_ := SDL_USEREVENT;
  8.   event.user.code := 1;
  9.   event.user.data1 := nil;
  10.   event.user.data2 := nil;
  11.  
  12.   if (SDL_PushEvent(event) <> 0) then
  13.     WriteLn('error pushing event');
  14.  
  15.   Result := 1000;
  16. end;


mit dem WriteLn alleine geht alles wunderbar.
Erst wollte ich direkt im Timer die Frames ausrechnen, anzeigen und die Variable zurücksetzen, aber im Wiki stand, dass das alles nicht threadsave ist und man events benutzen soll...

weiß jemand, warum er von dieser exotischen speicheradresse lesen will?
oder gibt es nen anderen weg, timer zu realisieren? ohne vcl und möglichst plattformunabhängig?

vielen dank für die Mühe!

edit:
der fehler tritt am ende der funktion auf, also gepusht wird...
ich teste noch weiter :?

editedit:
es öffnet sich außerdem dieses cpu-fenster, wenn der fehler kommt
wenn ich im einzelschritt durch den timer gehe und dann im cpu-fenster einmal f8 drücke und danach f9 läuft das programm weiter ohne die accesviolation, allerdings reagiert es nicht mehr wirklich auf seine umwelt...

edit3:
der fehler kommt auch, wenn ich das event nur definiere ohne es hinterher zu pushen
und er meint, event sei möglicherweise nicht initialisiert worden - kann man das bei records überhaupt??


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 12, 2008 12:39 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
event is ein pointer(zumindest sagt das sein Name) den du nicht initialisierst. Also darfst du ihn nicht dereferenzieren, was mit event.type_ automatisch geschieht (ist das selbe wie event^.type_)

Pointer sind eine der weniges stellen an der ich öfters die ungarische notation verwende. Würde die Variable auch PEvent nennen.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 12, 2008 14:36 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Was The-Winner dir damit sagen will: Reservier vorher den Speicher für deinen Pointer.
Code:
  1. GetMem(event, SizeOf(SDL_Event));


Aber achtung: Schau am besten nochmal in der Libsdl nach, wie das ist mit dem Freigeben. Entweder SDL übernimmt das für dich oder du musst dich selber darum kümmern. Auch möglich ist, dass SDL den Inhalt des Records für sich noch einmal Kopiert. Dann müsstest du folgenden Code verwenden:
Code:
  1. function TGame.FPSTimer(...):...;
  2. var
  3.   event: SDL_Event;
  4. begin
  5.   ... deine Zuweisungen ...
  6.  
  7.   if (SDL_PushEvent(@event) <> 0) then
  8.    WriteLn(...);
  9.  
  10.   ...
  11. end;


Wenn du in den Dokumentationen dazu nichts findest, verwende mal due erste Methode, die ich beschrieben habe und schau mit so einer Speicherleckfinderunit nach, ob dabei ein Leck entsteht oder nicht. Wenn nein: Gut is, SDL gibt frei, wenn ja, benutze die zweite Methode, die ich beschrieben habe.
So eine Unit ist für FreePascal dabei mitgeliefert... Wie hieß die doch gleich... HeapTrc.

Gruß Lord Horazont


// edit Lossy: Pascaltags korrigiert

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 12, 2008 15:09 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Also die erste Methode wird es wohl eher nicht sein, denn dann gehören die SDL Entwickler gesteinigt. Die Methode muss die übergebene Struktur kopieren etc. Alles andere würde dem Speichermanager von Delphi die Füße unter dem Boden wegziehen.

Denn die Speichermanager verwalten grundsätzlich alle immer selber eine Liste von reservierten Speicherbereichen. Und die sind Teil eine größeren Speicherblocks. Da darf niemand ohne die Erlaubniss den Speichermanagers etwas freigeben. Und dabei gibt es auch keine Ausnahme. Und solche SpeicherUnit wie FastMM stellen so etwas auch nur anhand diverser Listen fest, ob noch etwas übrig geblieben ist oder nicht.

PS: SDL_PushEvent ;) Also der zweite Vorschlag von Lord Horazont ist der glückliche Gewinner.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 12, 2008 17:10 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Achja, was mich noch interessiert: Wie übergibst du deinen Timer an SDL? Eigentlich dürfte das Methoden doch garnicht annehmen. Oder hast du da noch eine "Vermittlerfunktion" zwischen?

Gruß Lord Horazont
P.S.: @Lossy: Sorry für die Tags.

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 12, 2008 17:41 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 29, 2005 21:11
Beiträge: 88
Wohnort: Bonn
Vielen Dank für den Tip mit dem Pointer!
Ich habe ein bisschen nachgedacht und bin auf folgende Lösung gekommen, wo ich mich auf den ersten Blick nicht um Speicherlecks kümmern muss:
Code:
  1. function TGame.FPSTimer(Interval: UInt32; param: Pointer): Integer;
  2. var
  3.   event: TSDL_UserEvent;
  4. begin
  5.   WriteLn('FPSTimer');
  6.  
  7.   event.type_ := SDL_USEREVENT;
  8.   event.code := 1;
  9.   event.data1 := nil;
  10.   event.data2 := nil;
  11.  
  12.   SDL_PushEvent(@event)
  13.  
  14.   Result := 1000;
  15. end;


Also nicht Pointer zu nutzen, sondern direkt den Record.
Es scheint zu funktionieren, bis jetzt ist mir der Compiler noch nicht um die Ohren geflogen - ist es stilistisch auch akzeptabel?

Hui - jetzt muss ich erstmal die neuen Posts lesen =)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Feb 12, 2008 17:45 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 29, 2005 21:11
Beiträge: 88
Wohnort: Bonn
oops, die lösung hatte der Lord ja schon gepostet - nächstes mal lese ich den code aufmerksamer durch :oops:
ja, bei push_event wird die struktur kopiert, meine ich irgendwo gelesen zu haben

der timer ist ein SDL-Timer, den ich folgendermaßen erstelle:
SDL_AddTimer(1000, @TGame.FPSTimer, nil);
beantwortet das deine frage?


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 8 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 14 Queries | GZIP : On ]