Page 1 of 2

Structured pointer problem

Posted: Sat Mar 11, 2006 8:34 pm
by Trond
What is wrong with this code?

Code: Select all

AString.s = "Apple pie"
*ZString.String = @AString
Debug *ZString\s

Posted: Sat Mar 11, 2006 8:46 pm
by Dare2
Lots of pointers there.

Is Debug PeekS(*ZString) not the way?


How/why would you use something like that, rather than straightforward strings? In other words, what trick or tip do you have up your sleeve? :)

Re: Structured pointer problem

Posted: Sat Mar 11, 2006 8:54 pm
by blueznl
Trond wrote:What is wrong with this code?

Code: Select all

AString.s = "Apple pie"
*ZString.String = @AString
Debug *ZString\s
dunno, well, isn't *zstring pointing to the array descriptor instead of the string itself?

haven't tried it but ueh, perhaps debug peeks(*zstring\s)

Posted: Sat Mar 11, 2006 9:00 pm
by Dare2
But peeks(*zstring\s) would be (in theory, anyhow) trying to use a string as a number.

Either Trond's
.. Debug *Zstring\s (which fails, with invalid memory address)
or
.. Debug PeekS(*Zstring)

But what has me curious is what is the advantage of using this at all? :)

Posted: Sat Mar 11, 2006 9:06 pm
by netmaestro
If you're going to use pointers, you should stick with pointer logic. That means knowing the datatype you are after and identifying its offset in the structure:

Code: Select all


AString.s = "Apple pie" 
*ZString = @AString 
Debug PeekS(*zstring+OffsetOf(string\s))

But what has me curious is what is the advantage of using this at all?
You find a significant speed advantage with a heavy workload as it's all direct memory access. (it's more impressive with more complicated structures for sure)

Posted: Sat Mar 11, 2006 9:12 pm
by Trond
Dare2 wrote:But what has me curious is what is the advantage of using this at all? :)
I want to cast the address of a string to a string to avoid the speed penalty of a function call to PeekS().

Edit: Something like this, just a bit more elegant.

Code: Select all

String.s = "Apple pie"
Address = @String
*StringPtr.s

!mov eax, [v_Address]
!mov [p_StringPtr], eax

Debug *StringPtr

Posted: Sat Mar 11, 2006 9:13 pm
by Dare2
That is functionally the same as PeekS(*ZString) as the offset is 0. :) If the offset was not zero, it might be a problem as the address assignment was to *ZString and therefore the first 4 bytes contains the address of the string.

Too many pointers. :)

Trond's way should work, IMO. PeekS(*ZString) does work, so does the offset approach (being 0).

But, Trond, why? You have a trick you're working on?

Edit: Ah. (Posted same time)

Posted: Sat Mar 11, 2006 9:15 pm
by netmaestro
avoid the speed penalty of a function call to PeekS()
If you can manage that I'd like to know how, but afaik you can't get something for nothing.
That is functionally the same as PeekS(*ZString) as the offset is 0
Yes, but I'm just showing the generic way to get data from structures using pointers. Most real-world applications have more complicated structures.

Posted: Sat Mar 11, 2006 9:18 pm
by Dare2
netmaestro wrote:If you can manage that I'd like to know how, but afaik you can't get something for nothing.
Life's a begger that way. :)

Posted: Sat Mar 11, 2006 9:31 pm
by Trond

Code: Select all

AString.s = "Apple pie" 
*ZString.String = @AString 
Debug PeekS(*ZString) ; This should be the same as
Debug *ZString\s      ; this, since the offset is 0.
                      ; By using this structured pointer a lot of time can
                      ; saved since we don't have to call PeekS(), which in
                      ; turn most likely creates a temporary string buffer
                      ; (it's not simply a cast).
                      ; But, for some reason, the version without PeekS()
                      ; doesn't work. I thought at first it was a bug, but
                      ; I didn't want to say anything about that since I've
                      ; always used PeekS() before and I'm not much into using
                      ; pointers this way.
                      ; Now I think it's a bug.
netmaestro wrote:
avoid the speed penalty of a function call to PeekS()
If you can manage that I'd like to know how, but afaik you can't get something for nothing.
You can do it like this, but I thought that maybe there was a more elegant way using a structured pointer. Remember to declare the destination string as *pointer to a string, not a string, or you'll get som hard to trace memory leaks.

Code: Select all

PointerToString.l = @"Apple Pie"
*StringPtr.s 

!mov eax, [v_PointerToString]
!mov [p_StringPtr], eax 

Debug *StringPtr
That is functionally the same as PeekS(*ZString) as the offset is 0
Yes, but I'm just showing the generic way to get data from structures using pointers. Most real-world applications have more complicated structures.[/quote]I thought this structure was made exclusively for this very purpose, a speedup gain from avoiding PeekS(), so it would be as real-world as neccessary already?

Posted: Sat Mar 11, 2006 9:37 pm
by Dare2
Truth is, I think your original way should work (Debug *ZString\s).

Just wondering now if assigning addresses to the string structure and then accessing the string would be faster than PeekS. Can't really tell because can't test. :)

Posted: Sat Mar 11, 2006 9:40 pm
by Nik

Code: Select all

Structure ComplexStruct
Val1.q
Val2.d
Val3.f
Val4.l
Val5.s
EndStructure

Procedure.l DoSthWithStruct(*PStruct.ComplexStruct)
Debug *PStruct\Val1
Debug *PStruct\Val2+1.4
Debug *PStruct\Val2 ;* *PStruct\Val3
Debug *PStruct\Val5
EndProcedure


MyStruct.ComplexStruct
With MyStruct
\Val1=1858485
\Val2=1.6
\Val3=2.0
\Val5="Hallo Welt!"
EndWith

DoSthWithStruct(@MyStruct)
This is how to deal with Structures in Memory the smart way, no need to use Offset of in simple cases like this, it's only needed with mor complicated functions for example when sorting a structured List.

Code: Select all

AString.s = "Apple pie"
ZString.String
ZString\s=AString.s
*PString.String=@ZString
Debug *PString\s
works too!

Posted: Sat Mar 11, 2006 9:57 pm
by Trond
Nik wrote:

Code: Select all

AString.s = "Apple pie"
ZString.String
ZString\s=AString.s
*PString.String=@ZString
Debug *PString\s
works too!
It does work, but it's not much faster than using PeekS() since you do a copy of the string when you do ZString\s=AString.s. I wanted to cast a long to a string, and don't copy it.
Just wondering now if assigning addresses to the string structure and then accessing the string would be faster than PeekS. Can't really tell because can't test.
Definetely copying a pointer then accessing the string from the pointer would be faster than copying the entire string:

Code: Select all

AString.s = "Apple pie" 

#Tries = 10000000

; Fast way of doing it (don't copy the string, just move the pointer)
time = GetTickCount_()
For I = 0 To #Tries
  !mov  edx, [v_AString]
  !mov  [p_InSane], edx
  *InSane.s
Next
MessageRequester("", Str(GetTickCount_()-time))

; PeekS() way of doing it
time = GetTickCount_()
For I = 0 To #Tries
  *InSane.s = PeekS(@AString)
Next
MessageRequester("", Str(GetTickCount_()-time))

Posted: Sat Mar 11, 2006 10:08 pm
by Dare2
Trond wrote:Definetely copying a pointer then accessing the string from the pointer would be faster than copying the entire string
Ding ding. :? Quite right. :)

Posted: Sat Mar 11, 2006 10:18 pm
by Dare2
Too many pointers. This help, though?

Code: Select all

Structure tooMany
  StructureUnion
    Zstring.string
    ptr.l
  EndStructureUnion
EndStructure

  
test.tooMany
test\ptr = AllocateMemory(20)
PokeS(test\ptr,"Peaches and Pears")

Debug test\Zstring\s

FreeMemory(test\ptr)
Glad you started this discussion, because now I see advantage. :)