CPYMEM with arrays

Started by pjot, October 26, 2005, 02:48:59 AM

Previous topic - Next topic

pjot

Hi,



With "cpymem" it is possible to copy contents from one variable to another. This is handy when you want the startingaddress of the variable be the same. E.g.:



newLISP v.8.7.0 on Tru64Unix, execute 'newlisp -h' for more info.

> (set 'REF:a (array 2))
(nil nil)
> (set 'v "Blabla")
"Blabla"
> (set 'w "Testing")
"Testing"
> (address w)
335579424
> (cpymem v w 6)
6
> (println w)
Blablag
"Blablag"
> (address w)
335579424


However, if I try to perform a "cpymem" from a regular variable to an array variable, this does not work:



newLISP v.8.7.0 on Tru64Unix, execute 'newlisp -h' for more info.

> (set 'REF:a (array 2))
(nil nil)
> (nth-set 1 REF:a "newLisp")
nil
> (println (nth 1 REF:a))
newLisp
"newLisp"
> (println (address (nth 1 REF:a)))
335579360
335579360
> (set 'v "Blabla")
"Blabla"
> (cpymem v (nth 1 REF:a) 6)
6
> (println (nth 1 REF:a))
newLisp
"newLisp"
> (println (address (nth 1 REF:a)))
335579424
335579424
> (cpymem v (nth 1 REF:a) 6)
6
> (println (nth 1 REF:a))
newLisp
"newLisp"
> (println (address (nth 1 REF:a)))
335579168
335579168


The base address of the array variable changes all the time, and also, the contents remains the same. How come?



Peter

pjot

#1
It's even stranger:



newLISP v.8.7.0 on linux, execute 'newlisp -h' for more info.

> (set 'a (array 2))
(nil nil)
> (nth-set 1 a "Peter")
nil
> (println (a 1))
Peter
"Peter"
> (println (address (a 1)))
134817864
134817864
> (println (address (a 1)))
134817944
134817944
> (println (address (a 1)))
134817792
134817792
> (println (address (a 1)))
134817840
134817840
> (println (address (a 1)))
134818008
134818008


So every time when I print the address of an array member, the address changes....?!?!



Actually, I try to find a way to have multiple string variables (say about 100) whose starting address in memory remain the same. So for all kinds of reasons the starting address *must* remain the same; that is way I need the 'cpymem' also. And using a 100 individual variable names is very ugly.....



Is there a nice way to do this? Arrays don't work, unfortunately.



Peter

PaipoJim

#2
Quote from: "pjot"
So every time when I print the address of an array member, the address changes....?!?!



Peter


The manual defines "address" to work only with "int", "double flost", and "string".  There is some more documentation of memory management in the FAQ at:



http://newlisp.org/MemoryManagement.html">//http://newlisp.org/MemoryManagement.html



How about using an association list for the array that you set each time you assign a value to an int:

 

(setq indx 0)
(inc indx)
(push (cons ((sym (append (string (i (indx))))) (sym (adress (sym (append (string (i (indx))))))) alst -1)

"alst" would then be: ((i1 address) (i2 address) ... )


or some such.  Also, perhaps you could store the ints as chars in a string and index into that off of the string address.

-

pjot

#3
Hi PaipoJim,



Thanks for your suggestions! I actually did read that part in the manual about 'address', but the text is confusing. It informs us about ints, floats and strings, but it does not tell something about the 'type of variable', e.g. a plain symbol, list or array.



So I tried to use an array variable, assuming that an array of strings was kept in some sort of numbered C character pointer. I should have checked the newLisp source code myself first, though ;-)



I also thought to 'do something with sym', and I see your solution points in this direction. But you're using the 'cons' statement, which I never used myself before; I'll start studying it right now.



Thanks again for your solution!



Peter

PaipoJim

#4
Quote from: "pjot"


I also thought to 'do something with sym', and I see your solution points in this direction. But you're using the 'cons' statement, which I never used myself before;


Peter,



I think I might have left out a few functions in that last example.  However here is some working code I wrote yesterday that shows how to construct a context name from an array of ints and an array of capital letters.  It is instantiaing a context for a point in 3-dimensional space.  But you could use some functions like it to create an association list of int-address lists too...

(don't use flat as that un-conses the pairs!)




(define (merge lst1 lst2) (map cons lst1 lst2))

(setq XYZ '(X Y Z))

(setq xyz '(156 209 3))

(context (sym (join (map string (flat (merge XYZ xyz))))))
X156Y209Z3
X156Y209Z3>



-Jim

-