问题
One idea when using cvs
is to help the garbage collector by re-using a string buffer, like
/s 5 string def
s 2 cvs %...
s 66 cvs %...
However when doing such a thing in a loop, the strings actually found in the buffer were:
(-40.0)
(-30.0)
(-20.0)
(-10.0)
(0.0.0)
(10.00)
(20.00)
(30.00)
(40.00)
So it seems the strings are not terminated when conversion ended (Found in GhostScript 9.26). Unfortunately the GhostScript reference manual is somewhat silent about whether the string will be terminated or not.
So the question is: What is the expected behavior?
When trying something like val str dup 2 0 put cvs
the result was (as shown by ==
):
(-40.0)
(-30.0)
(-20.0)
(-10.0)
(0.0\0000)
(10.00)
(20.00)
(30.00)
(40.00)
So is re-using a string buffer a bad idea after all?
Update 1:
I found that the value put on the stack is correct, while the value in the buffer is not:
val s1 cvs pop % leaves the wrong value in s1
val s1 cvs /s2 exch def % leaves the correct value in s2
回答1:
Postscript strings are not C strings. In particular, they are not NUL-terminated; instead, they have explicit lengths, just like Postscript arrays. It is not possible to modify the length of a string (or array) once it is created, but it is possible to create a view ("interval" in Postscript terms) of a substring (or subarray). An interval is not a copy; it shares storage with the underlying string (array).
cvs
takes a string (to be used as a buffer) as an argument, overwrites the initial segment of the buffer with the value argument converted to a string, and returns that segment as an interval. (See page 568 of the PLRM; I'm too lazy to retype it.) You'll want to use that return value if you don't want garbage at the end of your converted value. (But the returned value will only be valid as long as you don't use the underlying buffer for something else.)
来源:https://stackoverflow.com/questions/57838019/postscript-does-cvs-terminate-the-string-buffer