【问题标题】:PostScript: Does `cvs` terminate the string buffer?PostScript:`cvs` 是否终止字符串缓冲区?
【发布时间】:2019-09-07 23:01:25
【问题描述】:

使用cvs 时的一个想法是通过重新使用字符串缓冲区来帮助垃圾收集器,例如

/s 5 string def
s 2 cvs %...
s 66 cvs %...

但是在循环中做这样的事情时,实际上在缓冲区中找到的字符串是:

(-40.0)
(-30.0)
(-20.0)
(-10.0)
(0.0.0)
(10.00)
(20.00)
(30.00)
(40.00)

所以转换结束时字符串似乎没有终止(在 GhostScript 9.26 中找到)。不幸的是,GhostScript 参考手册对于字符串是否会被终止有些沉默。

所以问题是:预期的行为是什么?

当尝试类似val str dup 2 0 put cvs 时,结果是(如== 所示):

(-40.0)
(-30.0)
(-20.0)
(-10.0)
(0.0\0000)
(10.00)
(20.00)
(30.00)
(40.00)

那么重用字符串缓冲区毕竟是个坏主意吗?

更新 1:

我发现放入堆栈的值是正确的,而缓冲区中的值不正确:

val s1 cvs pop            % leaves the wrong value in s1
val s1 cvs /s2 exch def   % leaves the correct value in s2

【问题讨论】:

    标签: string data-conversion postscript


    【解决方案1】:

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

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

    【讨论】:

    • 其实信息是传播的:第38页(数组):“另外,有一个操作符(getinterval)创建一个新的数组对象,它的值是一个现有数组的子区间;新旧对象共享该子区间中的数组元素。”,第 40 页(字符串):“复制字符串对象或创建子区间(子字符串)会导致共享字符串的值。 ”。我一直认为返回的值只是为了方便起见的缓冲区(解释第 568 页:“将文本存储到字符串 (...),并返回一个字符串对象,指定实际使用的子字符串。”) .
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多