Access Voilation mit SetLength

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Displaced
Beiträge: 83
Registriert: So 12. Jul 2009, 10:08

Access Voilation mit SetLength

Beitrag von Displaced »

Hallöchen,

Ich hab ein merkwürdiges Problem.
Ich bekomm bei einem Konstrukt von mir immer wieder nen Access Voilation fehler.
Aber ich werde daraus nicht schlau.

Code: Alles auswählen

procedure ClearMap(MapNum: Integer);
var
  i: Integer;
begin
  for i := 0 to High(Map[MapNum].Tile) do
    SetLength(Map[MapNum].Tile[i], 0)
  SetLength(Map[MapNum].Tile[0]);
  Map[MapNum].Name := '';
  Map[MapNum].Music := 'None.';
  Map[MapNum].MaxX := MAX_MAPX;
  Map[MapNum].MaxY := MAX_MAPY;
  SetLength(Map[MapNum].Tile, MAX_MAPX+1);
  App.PrintLn(ItoS(high(Map[MapNum].Tile)));
  for i := 0 to MAX_MAPX  do
    SetLength(Map[MapNum].Tile[i], MAX_MAPY+1);
  PlayersOnMap[MapNum] := NO;
  SetLength(MapCache[MapNum].Data, 0);
end;
Der Wert vom PrintLn lautet 24. was MAX_MAPX entspricht.
Und jetzt das Kuriose. Die Map die davor hier drin liegt, ist 100x100 groß (MapX und MapY) wenn ich das speicher ist alles okay.
Sobald ich 150x150 eintippel und speicher, gibts nen fehler, obwohl dieser Wert hier niemals vorkommt.
Mach ich da was grundlegendes Falsch?

Der Fehler tritt auch nur auf dem Linux Server auf. Auf Windows funktionier das Local ohne Probleme...

Okay wenn ich MAX_MAPX und Y auf 150 setze (konstante) dann funktioniert das alles einwandfrei.
Sobald ich was höheres rein setze hab ich wieder die probleme mit ner access voilation..
Scheinbar stimmt irgendwas nicht mit der speicher allokiierung -.-
Zuletzt geändert von Lori am Fr 2. Sep 2011, 15:58, insgesamt 1-mal geändert.
Grund: Highlighter

u-boot
Beiträge: 308
Registriert: Do 9. Apr 2009, 10:10
OS, Lazarus, FPC: Ubuntu 9.10 (L 0.9.28 FPC 2.2.4)
CPU-Target: 32Bit
Wohnort: 785..

Re: Access Voilation mit SetLength

Beitrag von u-boot »

Code: Alles auswählen

procedure ClearMap(MapNum: Integer);
var
  i: Integer;
begin
  for i := 0 to High(Map[MapNum].Tile) do
    SetLength(Map[MapNum].Tile[i], 0)
  SetLength(Map[MapNum].Tile[0]);  // ich würde raten: setlength(Map[MapNum].Tile, 0);  ?
  Map[MapNum].Name := '';
  Map[MapNum].Music := 'None.';
  Map[MapNum].MaxX := MAX_MAPX;
  Map[MapNum].MaxY := MAX_MAPY;
{  SetLength(Map[MapNum].Tile, MAX_MAPX+1);
  App.PrintLn(ItoS(high(Map[MapNum].Tile)));
  for i := 0 to MAX_MAPX  do
    SetLength(Map[MapNum].Tile[i], MAX_MAPY+1);}
setlength(Map[MapNum].Tile,   MAX_MAPX+1, MAX_MAPY+1)  //würde ich eher so schreiben, was nicht heissen soll, dass das andere falsch wäre... 
 
  PlayersOnMap[MapNum] := NO;
  SetLength(MapCache[MapNum].Data, 0);
end;
Einzelschritte ausführen lassen müsste zumindest die Zzeile rausfinden wo die AV auftritt.
Kannst ja mit ner if-abfrage zumindest einen Teil der Schritte in der Schleife dann überspringen lassen.
Ubuntu 9.10 (L 0.9.28 FPC 2.4.x)

Displaced
Beiträge: 83
Registriert: So 12. Jul 2009, 10:08

Re: Access Voilation mit SetLength

Beitrag von Displaced »

// ich würde raten: setlength(Map[MapNum].Tile, 0); ?
Stimmt, habe mich hier bloß vertippt!

Code: Alles auswählen

SetLength(Map[MapNum].Tile, MAX_MAPX+1, MAX_MAPY+1);
Das kannte ich noch nicht.

Das komisch ist, dass es bei meinen Debug versuchen zu merkwürdigen ergebnissen kommt.

Also wenn die Map 100x100 groß ist, funktioniert es.
Wenn die danach 120x120 groß ist, gibts den Fehler beim initialisieren irgendwo ab x = 40 ...
Komischerweise nur auf Linux.

Vielleich weil ich dämlicher weise 32bit linux kompiliere und auf nem 64bit System am laufen habe?
Ich probier mal weiter. Falls irgend einem irgend etwas einfällt lasst es mich wissen.

Map ist im übrigen eine Statische Array aus nem Rec die eben Tile als array of array of besitzt.
Zuletzt geändert von Lori am Fr 2. Sep 2011, 15:58, insgesamt 1-mal geändert.
Grund: Highlighter

Antworten