首页 > 解决方案 > PostScript: Does `cvs` terminate the string buffer?

问题描述

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

标签: stringdata-conversionpostscript

解决方案


Postscript 字符串不是 C 字符串。特别是,它们不是 NUL 终止的;相反,它们有明确的长度,就像 Postscript 数组一样。字符串(或数组)一旦创建就无法修改其长度,但可以创建子字符串(或子数组)的视图(Postscript 术语中的“间隔”)。间隔不是副本;它与底层字符串(数组)共享存储。

cvs将字符串(用作缓冲区)作为参数,使用转换为字符串的 value 参数覆盖缓冲区的初始段,并将该段作为间隔返回。(请参阅 PLRM 的第 568 页;我懒得重新输入它。)如果您不想在转换值的末尾出现垃圾,您将需要使用该返回值。(但返回值只有在您不将底层缓冲区用于其他用途时才有效。)


推荐阅读