Why is this code now broken in v6.12?

Just starting out? Need help? Post your questions and find answers here.
Randy Walker
Addict
Addict
Posts: 1008
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Why is this code now broken in v6.12?

Post by Randy Walker »

Einander gave us a very powerful code sample to insert or delete elements in an array:
https://www.purebasic.fr/english/viewto ... rtL#p36953

But it has a memory error when you try to run his example code. How can this be fixed? And Also, can we make this a feature request? -- insert(array()) , delete(array())
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
User avatar
STARGÅTE
Addict
Addict
Posts: 2228
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Why is this code now broken in v6.12?

Post by STARGÅTE »

If you run this old code under x64 processor, all pointers or buffer addresses have to be an integer type.

Code: Select all

Procedure DeleteL(DIR.i,ELEM.L,DM.L) 

Code: Select all

InsertL(VA.L,DIR.i,ELEM.L,DM.L) 
However, also CopyMemory() is miss-used in this code. For CopyMemory() the source and destination buffers may not overlap. But this is the case here. So you have to replace it with MoveMemory().
Besides that, this code wouldn't work for the last element, because the size in CopyMemory or MoveMemory have to be larger than 0.

This Code is not "powerful", it is just historical.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Randy Walker
Addict
Addict
Posts: 1008
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Why is this code now broken in v6.12?

Post by Randy Walker »

Oh but it is powerful, if you need to insert or delete elelments in an array. Maybe you have better way?

Anyway I checked value of @A() and determined from that I had encountered the classic All .L need to be changed to .i instead, so I did and code ran without any issue.
Thanks!!!
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
User avatar
STARGÅTE
Addict
Addict
Posts: 2228
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Why is this code now broken in v6.12?

Post by STARGÅTE »

But this code actually do not delete or insert an element. The array size keeps constant, it just moves the data.
If you insert an element in a full array, this code shifts out the last element.

Here is my version for DeleteArrayElement and InsertArrayElement, written as a macro, to allow multiple atomic data types for the arrays. However, such code (as well as the linked code) are not working with string-arrays or structured arrays.

Code: Select all

Macro DeleteArrayElement(ArrayName, Index)
	If Index >= 0 And Index <= ArraySize(ArrayName())
		If Index < ArraySize(ArrayName())
			MoveMemory(@ArrayName(Index+1), @ArrayName(Index), @ArrayName(ArraySize(ArrayName()))-@ArrayName(Index))
		EndIf
		If ArraySize(ArrayName()) > 0
			ReDim ArrayName(ArraySize(ArrayName())-1)
		Else
			FreeArray(ArrayName())
		EndIf
	EndIf
EndMacro

Macro InsertArrayElement(ArrayName, Index, Value)
	If Index >= 0
		If ArraySize(ArrayName()) = -1
			Dim ArrayName(Bool(Index>=0)*(Index))  ; Bool(Index>=0) is needed here to prevent compiler error for index < 0
		ElseIf Index > ArraySize(ArrayName())
			ReDim ArrayName(Bool(Index>=0)*(Index))  ; Bool(Index>=0) is needed here to prevent compiler error for index < 0
		Else
			ReDim ArrayName(ArraySize(ArrayName())+1)
		EndIf
		If Index < ArraySize(ArrayName())
			MoveMemory(@ArrayName(Index), @ArrayName(Index+1), @ArrayName(ArraySize(ArrayName()))-@ArrayName(Index))
		EndIf
		ArrayName(Index) = Value
	EndIf
EndMacro

Macro ViewArray(ArrayName)
	For I = 0 To ArraySize(ArrayName())
		Debug "[" + I + "] = " + ArrayName(I)
	Next
EndMacro

;- Example

Define Dim MyArray.f(3)

MyArray(0) = 1.0
MyArray(1) = 2.0
MyArray(2) = 3.0
MyArray(3) = 4.0

ViewArray(MyArray)

Debug "Delete:"
DeleteArrayElement(MyArray, 2)
ViewArray(MyArray)

Debug "Insert:"
InsertArrayElement(MyArray, 0, 3.25)
ViewArray(MyArray)

Debug "Insert:"
InsertArrayElement(MyArray, 7, 100)
ViewArray(MyArray)
Last edited by STARGÅTE on Sun Jan 26, 2025 10:45 am, edited 1 time in total.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
Randy Walker
Addict
Addict
Posts: 1008
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Why is this code now broken in v6.12?

Post by Randy Walker »

Ok. I got the original code to work properly. First all the .L variables had to be changed to .i instead and because I am running PB 64 bit the "4"values in both procedures had to be raised to "8". So here is Einander's code again tested and working for PB 64 bit (windows).:

Code: Select all

;By Einander - October 21 - 2003 - PB 3.80
;Procedure DeleteL(@Array(),ELEM,DM) deletes the item indexed by ELEM from Array.i().
; All array items whose indices are >= ELEM are shifted one position up.
; The value of the last element in the array is converted to 0.

Procedure DeleteL(DIR.i,ELEM.i,DM.i) 
  CopyMemory(DIR+(elem+1)*8,DIR+elem*8,(DM-elem)*8)
  PokeL(DIR+DM*8,0)
EndProcedure

; Procedure Insert(VA,@Array,ELEM,DM) inserts VA in Array.i() at position ELEM.
; All items in Array.i  whose indices are >= ELEM are moved one position down.
; The last element in ARRAY.i() is deleted with each Insert.
; Would be nice to icrease the size of the array to fit the last element.

Procedure InsertL(VA.i,DIR.i,ELEM.i,DM.i) 
  CopyMemory(DIR+elem*8,DIR+(elem+1)*8,(DM-elem)*8)
  PokeL(DIR+ELEM*8,VA)
EndProcedure

;::::::::::::::::::::::::::::::::::::::::

DM=10
ELEM=5    ;Element to delete

Dim A.i(DM)
For I=0 To DM : A(I)=I  : Next
Gosub TEST
Debug " "
DeleteL(@A(),ELEM,DM)  ;deletes item 5
Debug "Deleted "+Str(ELEM)
Debug " "
Gosub TEST

InsertL(555,@A(),5,DM)  ; inserts 555 at posic 5
Debug "Inserted 555"
Gosub TEST
MessageRequester("DONE","",0)
End

;     :::::::::::::::::::::::::::::::::::

TEST:
For I=0 To DM
  Debug Str(I)+"  "+Str(A(I))
Next I
Return
Sorry guys. I forgot to mention I was working with 64 bit PB. Master of I/O errors.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Why is this code now broken in v6.12?

Post by ChrisR »

STARGÅTE wrote: Sat Jan 25, 2025 10:56 pm Here is my version for DeleteArrayElement and InsertArrayElement, written as a macro...
Very pretty and works perfectly :)
In InsertArrayElement both (Re)Dim ArrayName(Bool(Index>=0)*(Index)) can be simplified to (Re)Dim ArrayName(Index), Index >= 0 is tested before
miso
Enthusiast
Enthusiast
Posts: 459
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Why is this code now broken in v6.12?

Post by miso »

@Randy Walker
If you want to use that version, then PokeL()-s should be replaced with PokeI()-s, *4 for 32 bit, *8 for 64 bit. Still, Stargate's version is perfect, no need to update or fix anything.
Randy Walker
Addict
Addict
Posts: 1008
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Why is this code now broken in v6.12?

Post by Randy Walker »

STARGÅTE wrote: Sat Jan 25, 2025 10:56 pm Here is my version for DeleteArrayElement and InsertArrayElement, written as a macro
IIII Like it!!! It's beautiful!
THANKS STARGATE :!: :!: :!:
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
User avatar
STARGÅTE
Addict
Addict
Posts: 2228
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: Why is this code now broken in v6.12?

Post by STARGÅTE »

ChrisR wrote: Sun Jan 26, 2025 12:45 am
STARGÅTE wrote: Sat Jan 25, 2025 10:56 pm Here is my version for DeleteArrayElement and InsertArrayElement, written as a macro...
Very pretty and works perfectly :)
In InsertArrayElement both (Re)Dim ArrayName(Bool(Index>=0)*(Index)) can be simplified to (Re)Dim ArrayName(Index), Index >= 0 is tested before
Unfortunately not^^. Bool(Index>=0) is just a dummy to prevent evaluation during compilation.
Otherwise, for Index = -1, the Macro is evaluated to

Code: Select all

If -1 >= 0
		If ArraySize(ArrayName()) = -1
			Dim ArrayName(-1)
and then the compiler gives an error that Dim ArrayName(-1) have to be positive, even If -1 >= 0 would be false.
I can't use CompilerIf, because then Index must be a constant at all, which I don't want.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
infratec
Always Here
Always Here
Posts: 7598
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Why is this code now broken in v6.12?

Post by infratec »

And for your 4 to 8 transitions, you should use

Code: Select all

SizeOf(Integer)
Else your code is not working in the x86 version of PB :wink:
User avatar
ChrisR
Addict
Addict
Posts: 1466
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Why is this code now broken in v6.12?

Post by ChrisR »

STARGÅTE wrote: Sun Jan 26, 2025 9:06 am Unfortunately not^^. Bool(Index>=0) is just a dummy to prevent evaluation during compilation.
Thanks for the explanation, not tested with Index = -1, nice workaround then :)
Randy Walker
Addict
Addict
Posts: 1008
Joined: Sun Jul 25, 2004 4:21 pm
Location: USoA

Re: Why is this code now broken in v6.12?

Post by Randy Walker »

infratec wrote: Sun Jan 26, 2025 9:54 am And for your 4 to 8 transitions, you should use

Code: Select all

SizeOf(Integer)
Else your code is not working in the x86 version of PB :wink:
Ok, this i a curious comment. When I try this code (below) I get syntax error on line 2. What did I do wrong?
a.i = 42
Debug SizeOf(a.i)
I tried the original code modified like this (below) but even on a 32 bit machine, it gave results that should happen only on a 64 bit machine. And of course both procedures failed to produce any results.

Code: Select all

;By Einander - October 21 - 2003 - PB 3.80
;Procedure DeleteL(@Array(),ELEM,DM) deletes the item indexed by ELEM from Array.i().
; All array items whose indices are >= ELEM are shifted one position up.
; The value of the last element in the array is converted to 0.
Global bits
a.i = 2147483648  ;<< This is max value for 4 byte integer Plus one!!!
If a.i = 2147483648
  bits = 64
  Debug "64 bit"
Else
  Debug "32 bit"
EndIf

Procedure DeleteL(DIR.i,ELEM.i,DM.i)
  If bits = 64
    CopyMemory(DIR+(elem+1)*8,DIR+elem*8,(DM-elem)*8)
    PokeL(DIR+DM*8,0)
  Else
    CopyMemory(DIR+(elem+1)*4,DIR+elem*4,(DM-elem)*4)
    PokeL(DIR+DM*4,0)
  EndIf
EndProcedure

; Procedure Insert(VA,@Array,ELEM,DM) inserts VA in Array.i() at position ELEM.
; All items in Array.i  whose indices are >= ELEM are moved one position down.
; The last element in ARRAY.i() is deleted with each Insert.
; Would be nice to icrease the size of the array to fit the last element.

Procedure InsertL(VA.i,DIR.i,ELEM.i,DM.i)
  If bits = 64
    CopyMemory(DIR+elem*8,DIR+(elem+1)*8,(DM-elem)*8)
    PokeL(DIR+ELEM*8,VA)
  Else
    CopyMemory(DIR+elem*4,DIR+(elem+1)*4,(DM-elem)*4)
    PokeL(DIR+ELEM*4,VA)
  EndIf
EndProcedure

;::::::::::::::::::::::::::::::::::::::::

DM=10
ELEM=5    ;Element to delete

Dim A.i(DM)
For I=0 To DM : A(I)=I  : Next
Gosub TEST
Debug " "
DeleteL(@A(),ELEM,DM)  ;deletes item 5
Debug "Deleted "+Str(ELEM)
Debug " "
Gosub TEST

InsertL(555,@A(),5,DM)  ; inserts 555 at posic 5
Debug "Inserted 555"
Gosub TEST
MessageRequester("DONE","",0)
End

;     :::::::::::::::::::::::::::::::::::

TEST:
For I=0 To DM
  Debug Str(I)+"  "+Str(A(I))
Next I
Return

 
I still get "64 bit" from the debug line when run on the 32 bit machine, so I'm very lost on this issue. Fortunately STARGATE provideed a working solution.
- - - - - - - - - - - - - - - -
Randy
I *never* claimed to be a programmer.
User avatar
idle
Always Here
Always Here
Posts: 5863
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Why is this code now broken in v6.12?

Post by idle »

use sizeof(integer)

Code: Select all

;By Einander - October 21 - 2003 - PB 3.80
;Procedure DeleteL(@Array(),ELEM,DM) deletes the item indexed by ELEM from Array.i().
; All array items whose indices are >= ELEM are shifted one position up.
; The value of the last element in the array is converted to 0.

Procedure DeleteI(DIR.i,ELEM.i,DM.i)
 CopyMemory(DIR+(elem+1)*SizeOf(integer),DIR+elem*SizeOf(integer),(DM-elem)*SizeOf(integer))
 PokeI(DIR+DM*SizeOf(integer),0)
EndProcedure

; Procedure Insert(VA,@Array,ELEM,DM) inserts VA in Array.i() at position ELEM.
; All items in Array.i whose indices are >= ELEM are moved one position down.
; The last element in ARRAY.i() is deleted with each Insert.
; Would be nice to icrease the size of the array to fit the last element.

Procedure InsertI(VA.i,DIR.i,ELEM.i,DM.i)

CopyMemory(DIR+elem*SizeOf(integer),DIR+(elem+1)*SizeOf(integer),(DM-elem)*SizeOf(integer))
PokeI(DIR+ELEM*SizeOf(integer),VA)

EndProcedure

;::::::::::::::::::::::::::::::::::::::::

DM=10
ELEM=5 ;Element to delete

Dim A.i(DM)
For I=0 To DM : A(I)=I : Next
Gosub TEST
Debug " "
DeleteI(@A(),ELEM,DM) ;deletes item 5
Debug "Deleted "+Str(ELEM)
Debug " "
Gosub TEST

InsertI(555,@A(),5,DM) ; inserts 555 at posic 5
Debug "Inserted 555"
Gosub TEST
MessageRequester("DONE","",0)
End

; :::::::::::::::::::::::::::::::::::

TEST:
For I=0 To DM
Debug Str(I)+" "+Str(A(I))
Next I
Return
User avatar
IceSoft
Addict
Addict
Posts: 1693
Joined: Thu Jun 24, 2004 8:51 am
Location: Germany

Re: Why is this code now broken in v6.12?

Post by IceSoft »

See the different sizes:

Code: Select all

Debug SizeOf(Integer)
Debug SizeOf(Long)
Debug SizeOf(Word)
Debug SizeOf(Byte)
And last but Not least:
A PureBasic pointer variable should be ALWAYS a Integer like:

Code: Select all

myPointer.i
Belive! C++ version of Puzzle of Mystralia
Bug Planet
<Wrapper>4PB, PB<game>, =QONK=, PetriDish, Movie2Image, PictureManager,...
User avatar
mk-soft
Always Here
Always Here
Posts: 6226
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Why is this code now broken in v6.12?

Post by mk-soft »

Better *myPointer
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Post Reply