Page 1 of 1
PokeS() vs *String\s
Posted: Tue Feb 25, 2025 9:36 am
by Justin
Is it legal to do this or are both options wrong?
Code: Select all
EnableExplicit
Procedure test(st.i)
Protected.String *s
*s = @st
*s\s = "foo" ;OK?
;PokeS(st, "foo") ;Wrong?
EndProcedure
Define.s st
st = ""
test(@st)
Debug st
Re: PokeS() vs *String\s
Posted: Tue Feb 25, 2025 10:08 am
by infratec
Enable Purifier and set granularity to 1, 1, 1, 1
Then you should see that both is wrong.
You don't have the place to store the string.
You can do
Re: PokeS() vs *String\s
Posted: Tue Feb 25, 2025 10:19 am
by STARGÅTE
Both codes are wrong.
With PokeS(), you did not allocate the additional needed memory, which causes an IMA.
With *s\s you write a new string and the memory address could change, so the main string is not affacted:
Code: Select all
EnableExplicit
Procedure test(st.i)
Protected.String *s
*s = @st
*s\s = "Hello World"
Debug "Local: " + @*s\s
;PokeS(st, "foo") ;Wrong?
EndProcedure
Define.s st
st = "123"
Debug "Main: " + @st
test(@st)
Debug "Main: " + @st
Debug st
You should use the String-Structure in the Main-Code and Procedure:
Code: Select all
Procedure test(*s.String)
*s\s = "Hello World"
EndProcedure
Define MyString.String
MyString\s = "123"
test(@MyString)
Debug MyString\s
Re: PokeS() vs *String\s
Posted: Tue Feb 25, 2025 12:06 pm
by SMaag
@justin
Why you want to to this?
If you want to speed up String-Parameters in Procedures - if you don't want PB to copy the String!
The solution is Prototype your Procedure. Then PureBasic pass the StringPointer directly and do not make a copy
of the String.
here is an example for
Code: Select all
EnableExplicit
Prototype.i ReplaceChar(String$, cSearch.c, cReplace.c) ; ProtoType-Function for ReplaceChar
Global ReplaceChar.ReplaceChar ; define Prototype-Handler for CountChar
Procedure.i _ReplaceChar(*String, cSearch.c, cReplace.c)
Protected *char.Character ; Pointer to a virutal Char-Struct
Protected N
*char = *String
If *char
While *char\c ; until end of String
If *char\c = cSearch
*char\c = cReplace ; replace the Char
N + 1
EndIf
*char + SizeOf(Character) ; Index to next Char
Wend
EndIf
ProcedureReturn N
EndProcedure
ReplaceChar = @_ReplaceChar() ; Bind ProcedureAdress to the PrototypeHandler
Define Txt$="1234561.123456111"
Debug Txt$
ReplaceChar(Txt$, '1', 'A') ; Txt$ is passed as @Txt$
Debug Txt$
Re: PokeS() vs *String\s
Posted: Tue Feb 25, 2025 12:44 pm
by Justin
So both are wrong, thanks!
Re: PokeS() vs *String\s
Posted: Tue Feb 25, 2025 2:49 pm
by AZJIO
Justin wrote: Tue Feb 25, 2025 9:36 am
If you pass the pointer, then you must accept it as a pointer
Or pointer to the structure
Justin wrote: Tue Feb 25, 2025 9:36 am
Here, "st" is a pointer, and you again take the pointer from it. You don't have a string in the pointer, but a number pointer.
Re: PokeS() vs *String\s
Posted: Tue Feb 25, 2025 3:33 pm
by STARGÅTE
AZJIO wrote: Tue Feb 25, 2025 2:49 pm
Justin wrote: Tue Feb 25, 2025 9:36 am
Here, "st" is a pointer, and you again take the pointer from it. You don't have a string in the pointer, but a number pointer.
This part of Justin's code is right.
"st" is a pointer (integer) and you have to receive its pointer as well to take it over to the String-Structure .String, because here you have a Pointer to a Structure its first field is a pointer to a string.
Code: Select all
Define String.s = "Hello World" ; The string
Define *Pointer = @String ; Pointer to the String content itself
Define *StringStructure.String = @*Pointer ; Pointer to the String-Pointer
Debug *StringStructure\s
However, this way is read-only. During write, you would change the string location in memory, which is not reflected back to String.s
Re: PokeS() vs *String\s
Posted: Tue Feb 25, 2025 3:43 pm
by AZJIO
STARGÅTE
Yes, you're right, I forgot that lately I've been using *c.Character pointers, where you need to take a pointer 1 time.
Re: PokeS() vs *String\s
Posted: Tue Feb 25, 2025 3:56 pm
by AZJIO
I've experimented with such a feature before. If you are passing a pointer instead of a structure, then you cannot increase the length of the string, since it is declared in the outer scope. If the author of the topic has passed an empty string and then writes data to it, then he will simply break the memory.
Code: Select all
Procedure.s TrimLeft(*a, n)
Protected *p.string = @*a
*p\s = Right(*p\s, Len(*p\s) - n)
EndProcedure
tmp$ = "Hello world"
TrimLeft(@tmp$, 3)
Debug tmp$
Instead of test(@st), you should use:
Re: PokeS() vs *String\s
Posted: Tue Feb 25, 2025 4:01 pm
by STARGÅTE
AZJIO wrote: Tue Feb 25, 2025 3:56 pm
If you are passing a pointer instead of a structure, then you cannot increase the length of the string, since it is declared in the outer scope.
Exactly.