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

19.01.2018, 23:05

Speicheränderung durch Funktionsaufruf? C++

Hallo, ich bin auf ein recht interessantes Problem gestoßen:

Ich habe drei für dieses Problem relevante Objekte:

Der Logger: schreibt Debugtext in mehrere Textfiles ( eines für den Renderer, eines für die Datenbank, etc. )

Der Manager: wandelt die Weltdaten in Renderdaten um

Camera: dient der Berechnung von Weltdaten in Renderdaten und einigen anderen Spielerelevanten Berechnungen


Der Logger funktioniert recht einfach durch einen Funktionsanruf dem man den gewünschten Text und das dafür gewünschte File übergibt.
Falls dieses File noch nicht existiert wird ein neues erstellt. Dafür hat er einen Vector von Strings ( nennen wir ihn FileNameKeeper ) in denen die verschiedenen Namen speichert und gegebenenfalls vergleicht (as simple as possible).

Nun habe ich die Cameraklasse um eine Funktion erweitert die zwei Integer übergeben bekommt und diese als Bildschirmposition der Camera festlegt.
die Funktion sieht so aus:

C-/C++-Quelltext

1
2
3
4
5
6
void Camera::setScreenPosition( int x, int y ){

screenPosition.x = x;
screenPosition.y = y;

}


Diese Funktion ist weder virtuell noch static.
Diese Funktion wird vom Manager einmal in seinem Konstruktor aufgerufen ( ich weiß, schlechtes Design, das wird noch überarbeitet )
Sie funktioniert auch wie gewünscht( oder auch nicht, siehe folgendes ), außer ich füge Debugtext hinzu:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Camera::setScreenPosition( int x, int y ){

if( x < 0 || y < 0 ) {

    Logger.write( Mainlog, "Cameraposition(s) incorrect" );

}
else{

    screenPosition.x = x;
    screenPosition.y = y;

    Logger.write( Mainlog, "Camerapositions changed" );

}

}


Dies gab mir einen lustigen Speicherzugriffsfehler aus.

Mir fiel auf, dass Mainlog zu dem Zeitpunkt bereits existiert und trotzdem versucht wurde ein neues zu erstellen. Das durfte garnicht passieren und ich habe die Eingaben überprüft. Diese waren durchaus korrekt, Mainlog wurde davor einige Male problemlos das Ziel von Funktionsaufrufen und hat den Text erfolgreich in die Datei geschrieben aber wenn es in der Camerafunktion aufgerufen wurde nicht.

Nachdem ich nun sicher sein konnte, dass der Input richtig ist ( oder es aus meiner Sicht zumindest richtig zu sein scheint ) habe ich kontrolliert womit er diese Eingaben vergleicht. Somit habe ich mir die Daten von FileNameKeeper jedes Mal ausgeben lassen wenn Debugtext geschrieben werden sollte. Diese Daten waren auch korrekt, bis die Camerafunktion aufgerufen wurde, da erhielt ich mal wieder einen Speicherzugriffsfehler.

Also sah ich mir die Größe von FileNameKeeper an. Sie ist bis auf 5 gewachsen ( soweit alles korrekt ). Doch wurde sie in der Camerafunktion aufgerufen hatte sie auf einmal die Größe 3 mit undefiniertem Inhalt :pillepalle:

Ok, ich habe das weiter ausgebaut und habe mir nun zusätzlich zu den Zeiten vor, während und nach dem Funktionsaufruf die Größe von FileNameKeeper ausgeben lassen.

Vor dem Funktionsaufruf: gewachsen bis auf 5 (soweit korrekt habe auch 5 verschiedene Logfiles)

Während dem Funktionsaufruf: 3 :dash:

Nach dem Funktionsaufruf: 5 :dash: :dash: :dash:

Das lustige dabei ist, auch wenn ich jedweden Debugtext und alles damit verbundene aus der Funktion entferne, also wirklich nur die Variablen zuweise (wie im ersten Codebeispiel) beträgt die Größe von FileNameKeeper während des Funktionsaufruf 3 -> unbekannter Inhalt -> Speicherzugriffsfehler
(außer natürlich die Größe ausgeben zu lassen, ich will hier nur daraufhinweisen, dass die Größe vom Beginn bis zum Ende der Funktion 3 beträgt, übrigens auch wenn ich die Funktion öfters aufrufe...)

Kann mir das bitte jemand erklären?

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »Wheee321« (20.01.2018, 00:02)


Tobiking

1x Rätselkönig

  • Private Nachricht senden

2

20.01.2018, 01:04

Wie erzeugst du denn den Logger und wie kommt deine Camera Klasse da dran?

Aus deiner Beschreibung würde ich darauf tippen, dass du entweder eine neue Logger Instanz erzeugst oder dir in der Camera Klasse den Verweis auf deine existierende Instanz kaputt machst. Der undefinierte Inhalt deutet dabei eher auf letzteres.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

3

20.01.2018, 04:53

Es gibt je nach IDE die Möglichkeit alle Änderungen an einem Speicherbereich zu überwachen. Ggf hilft das die Fehlerquelle zu finden. Für VS könnte es so gehen: https://stackoverflow.com/questions/1261…nges-or-is-read
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

20.01.2018, 09:01

Kann mir das bitte jemand erklären?
Nö. Jedenfalls nicht anhand dieser winzigen Code-Ausschnitte.
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]

5

20.01.2018, 14:20

Wie erzeugst du denn den Logger und wie kommt deine Camera Klasse da dran?

Aus deiner Beschreibung würde ich darauf tippen, dass du entweder eine neue Logger Instanz erzeugst oder dir in der Camera Klasse den Verweis auf deine existierende Instanz kaputt machst. Der undefinierte Inhalt deutet dabei eher auf letzteres.


Danke, das war der Fehler, es wird beim erstellen der Cameraklasse eine Referenz auf den Logger übergeben und ich habe das & innerhalb der Konstruktorparameterliste vergessen. Ich habe lustigerweise innerhalb der anderen Klassen Kontrollen ob das Objekt öfters erstellt wurde nur nicht beim Logger -> wird sofort geändert!


Es gibt je nach IDE die Möglichkeit alle Änderungen an einem Speicherbereich zu überwachen. Ggf hilft das die Fehlerquelle zu finden. Für VS könnte es so gehen: https://stackoverflow.com/questions/1261…nges-or-is-read


Das werde ich mir für die Zunkunt merken, dankeschön.

Werbeanzeige