Recent

Author Topic: Deleting elements from dynamic array causes crash when compiled for win 64bit.  (Read 2728 times)

acp693

  • Jr. Member
  • **
  • Posts: 73
Hi all,

I have the following test code which deletes elements from dynamic arrays. It works perfectly when compiled for 32bit win, but crashes when compiled for 64bit win. Is it to do with the fact that integers are different sizes on 64bit machines? I tried replacing the integers with int16, but made no difference. setting a watch on arr, I notice that when compiled for 64bit, the array arr is completely empty after being passed to the delete procedure. Any ideas what might be wrong?

Thanks.


Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;
  9. Type
  10.       TintArray = array of integer;
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     procedure FormShow(Sender: TObject);
  17.   private
  18.     { private declarations }
  19.   public
  20.     { public declarations }
  21.     procedure DeleteElementFromArrayInt(var A: Tintarray; const Index: integer);
  22.  
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.   arr: array of array of integer;
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. procedure TForm1.FormShow(Sender: TObject);
  33. begin
  34.     setlength (arr , 3);
  35.  
  36.     setlength (arr[0], 2);   //Build arr  with different lengths of second dimension
  37.     setlength (arr[1], 3);
  38.     setlength (arr[2], 2);
  39.  
  40.     arr[0,0]:= 8;       //filling arrays
  41.     arr[0,1]:= 9;
  42.  
  43.     arr[1,0]:= 5;
  44.     arr[1,1]:= 6;
  45.     arr[1,2]:= 7;
  46.  
  47.     arr[2,0]:= 3;
  48.     arr[2,1]:= 4;
  49.     DeleteElementFromArrayInt(TintArray(arr),1);    // delete all elements of second column of arr
  50.  
  51.     // show that all 3 elements of arr[1] are deleted and replaced by arr[2]
  52.     ShowMessage(IntToStr(arr[1,1]) + '  ' + IntToStr(arr[0,1]));
  53. end;
  54.  
  55. procedure TForm1.DeleteElementFromArrayInt(var A: Tintarray; const Index: integer);
  56.  
  57. var
  58.  ALength: integer;
  59.  TailElements: integer;
  60. begin
  61.  ALength := Length(A);
  62.  Assert(ALength > 0);
  63.  Assert(Index < ALength);
  64.  Finalize(A[Index]);
  65.  TailElements := ALength - Index;
  66.  if TailElements > 0 then
  67.     Move(A[Index + 1], A[Index], SizeOf(integer) * TailElements);
  68.  Initialize(A[ALength - 1]);
  69.  SetLength(A, ALength - 1);
  70. end;
  71.  
  72.  
  73.  
  74.  
  75. end.                        
« Last Edit: December 01, 2021, 10:11:17 am by acp693 »

acp693

  • Jr. Member
  • **
  • Posts: 73
Ok, I saw it almost straight away after I posted; Tintarray is only 1 dimension whereas arr has 2.

Still don't know why that would compile and work for 32bit and not 64bit.

Handoko

  • Hero Member
  • *****
  • Posts: 4523
  • My goal: build my own game engine using Lazarus
Still don't know why that would compile and work for 32bit and not 64bit.

Coincidence, I guess. Try with different data, I don't think that still will work correctly on 32-bit.

Because, you're type casting a wrong data type in line #49, which causes memory problem.

By changing line #9 of your code to:
Code: Pascal  [Select][+][-]
  1.   TintArray = array of array of integer;

I got this:
« Last Edit: December 01, 2021, 10:47:34 am by Handoko »

acp693

  • Jr. Member
  • **
  • Posts: 73
Yes, thankyou. :)

PascalDragon

  • Hero Member
  • *****
  • Posts: 4014
  • Compiler Developer
Still don't know why that would compile and work for 32bit and not 64bit.

As Handoko wrote: coincidence. If you have wrong code essentially all bets are off: it can work, it might not compile, it might raise an exception, it might cure world hunger or trigger an apocalypse. All possible...

 

TinyPortal © 2005-2018