postscript数组 最大尺寸?
我写了一个PS文档,其中包含一个显示在ghostview中的数组而没有任何问题。
但是当此数组中的项数增加时,ghostview会引发以下异常:
ERROR: /stackoverflow in -file-
Operand stack:
--nostringval--
Execution stack:
%interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- false 1 %stopped_push 1 3 %oparray_pop 1 3 %oparray_pop 1 3 %oparray_pop 1 3 %oparray_pop .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push
Dictionary stack:
--dict:1122/1686(ro)(G)-- --dict:0/20(G)-- --dict:122/200(L)--
Current allocation mode is local
Last OS error: 2
Current file position is 301163
ESP Ghostscript 815.02: Unrecoverable error, exit code 1
答案 0 :(得分:3)
最大阵列长度: 65535 。这也是最大字符串长度。但这似乎不是问题所在。
Postscript Level 2删除了堆栈大小的限制,因此它应该自动扩展到虚拟内存系统可以管理的任何大小。如果你遇到/ stackoverflow错误;您需要将解释器升级到至少2级(1991)标准。
编辑:也就是说,如果无法升级,有办法解决问题。
最有可能发生限制,因为堆栈是静态分配的。如果您可以访问源代码,则可以简单地增加大小并重新编译解释器。 PLRM 1ed中引用的限制为500。
另一种选择是改变你使用堆栈的方式(更难)。如果无法使用[]
或{}
构造1000个元素数组,则仍可以分配数组(1000 array
)并使用正常构造的切片(dup dup 0 [ 0 1 .. 450 ] putinterval dup dup 450 [ 451 452 .. 900 ] putinterval dup dup 900 [ 901 902 .. 999 ] putinterval
)填充它。记住,标记也会占用堆栈空间;某些操作员确实是程序,他们需要堆栈空间才能运行。
编辑:如果数组真的很大,那么阵列切片可能会使你的总内存限制更高;因为如果你没有增长的堆栈,你可能也没有垃圾收集。上述方法在VM中使用了1000个数组元素并且无法访问。使用packedarray
作为切片可能会稍微解决这个问题。
下一步是编写一个类似putinterval和packedarray混合的过程,它可以将数据加载到数组中而无需创建临时数组。由于我们正在重新实现更高级别的低级功能,因此可能会运行得更慢。
这是第一次尝试。它向前读取(使用currentfile token
)并将每个元素放入数组的后续位置。 arrayfill
必须是源代码行上的最后一个单词(如image
),因此currentfile可以找到第一个元素(源代码行的其余部分位于内部扫描程序缓冲区中)。
% array index count arrayfill(NL) array
% elem_0 elem_1 ..
% elem_count-1
/arrayfill { %a i c
1 index add 1 sub %a ini fin
1 exch { %a i
2 copy %a i a i
currentfile token pop %a i a i el
put %a i
pop %a
} for
} def
%example
5 array 0 5 arrayfill
(0) (1) (2) (3) (4)
{=} forall