Why does this not work as you would expect. This has been driving me mad all afternoon.
The procedure in the module is returning the newly created structure, or at least the memory location as you cannot return a structure from a procedure for some reason.
I am then creating a pointer structure and assinging that memory value to it, and then attempting to access the variable in that pointed structure but its always zero or garbage. I have included the code below. is it just because I am trying to do something I shouldn't ? It makes sense to me this would work.
This is all just test code to see how all these things hang together. Any advice would be welcome. Can confirm that memory addresses of all the debugs are as you expect except the final variable debug
You never 'create' something new.
You only return an address of a structure which gones after your next call.
If you want to create something dynamically, than you have to use AllocateMemory() or, in your case, AllocateStructure()
for 'creation'. And if it is later not needed anymore, you have to free it.
Bernd
Last edited by infratec on Fri Jan 08, 2016 8:50 pm, edited 1 time in total.
I suggest you to read well the manual about pointers and structures, and to do more experiments with them and some code simpler than this one because a lot of things here makes no sense whatsoever.
Start simpler.
To answer your question, you are creating a structure newEnemy of type object on the stack of the procedure createEnemy().
Then you return the base address of that structure and exit the procedure.
Upon leaving, the space on the stack for that structure and any other local variable is freed.
Then you try to access an element from that structure which does not exists anymore by coping its defunct address to a structured pointer of type object.
So you get garbage.
Other suggestions: use EnableExplicit, use Define or Global to define a var instead of throwing its name.type in the middle of the source (IMO the compiler should complain there because it has no meaning), and use @ when passing the address of a structure (it could help you in the future).
Yes, PB cannot return a structure, you can implement e mechanism to copy back a structure in a passed buffer preallocated by the caller if you like, see CopyStructure() and its family, it's equivalent of what many languages returning structures do, only there is invisible.
And yes, to dynamically allocate an "object" you have to allocate it by yourself like infratec said.
edit: pasted something in the wrong place...
Last edited by sys64802 on Fri Jan 08, 2016 8:42 pm, edited 2 times in total.
Structure out
sum.i
sqr.f
Array s$(10)
EndStructure
Procedure ReturnStructure(*ret, a, b, c, s$)
Protected ret.out
ret\sum = a + b + c
ret\sqr = Sqr(a+b+c)
For i = 0 To 10
ret\s$(i) = s$
Next
CopyStructure(@ret, *ret, out)
EndProcedure
Procedure test()
Protected RetVal.out
ReturnStructure(@RetVal, 10, 20, 30, "Hallo")
; equivalent to the unsupported:
; RetVal = ReturnStructure(10, 20, 30, "Hallo")
Debug RetVal\sum
Debug RetVal\sqr
Debug RetVal\s$(0)
Debug RetVal\s$(10)
; something like this has the advantage the "returned" value is deallocated automatically at procedure exit
; without the need to track its address and use Free*.*() on it
; the nice feature you get with real objects ...
EndProcedure
test()
This is not limited to work with a single type of structure either, just use a magic number at the start of the structure to identify its type and then go crazy, in a awkward way because you can just do only so much with the language (for example, no casting).
Thanks for all the pointers ( pun intended) people.
I was originally using @ to return address, but found that returning the variable name produced the same results.
Of course I really didn't thin about the fact that it would be removed from memory once the module had completed, especially as the manual told me tat kind of.
Is there a better version of the help. Have seen quite a few commands either in others code or by the auto-complete that have no entries in the help files
sys64802 wrote:I suggest you to read well the manual about pointers and structures, and to do more experiments with them and some code simpler than this one because a lot of things here makes no sense whatsoever.
Start simpler.
To answer your question, you are creating a structure newEnemy of type object on the stack of the procedure createEnemy().
Then you return the base address of that structure and exit the procedure.
Upon leaving, the space on the stack for that structure and any other local variable is freed.
Then you try to access an element from that structure which does not exists anymore by coping its defunct address to a structured pointer of type object.
So you get garbage.
Other suggestions: use EnableExplicit, use Define or Global to define a var instead of throwing its name.type in the middle of the source (IMO the compiler should complain there because it has no meaning), and use @ when passing the address of a structure (it could help you in the future).
Yes, PB cannot return a structure, you can implement e mechanism to copy back a structure in a passed buffer preallocated by the caller if you like, see CopyStructure() and its family, it's equivalent of what many languages returning structures do, only there is invisible.
And yes, to dynamically allocate an "object" you have to allocate it by yourself like infratec said.
edit: pasted something in the wrong place...
Thanks for all the suggestions
Trying to avoid globals and such. I could do things simpler and its my fault for trying to enforce good encapsulation etc on BASIC
Hadn't noticed allocate memory and the such thanks.
Might post my simpler code when I had more of a play around
s0ula55a551n wrote:
Is there a better version of the help. Have seen quite a few commands either in others code or by the auto-complete that have no entries in the help files
The help afaik include all the PB commands, maybe not all are indexed but if you read all the help at least once you will find them.
Maybe the other commands you saw are API functions ? Ending with "_" ?
In that case they are not documented and you have to refer to the OS documentation.