【发布时间】:2013-12-02 12:17:59
【问题描述】:
我有一些通过引擎 C API 与 Matlab 通信的 C++ 代码。我的代码在 Matlab 工作区中创建了临时变量,它会尽快通过clear 调用对其进行清理。但是,在某些时候,我的应用程序失败了,告诉我它无法创建下一个 Matlab 临时变量(通常在 ~65530 次这样的操作之后)。
在对 Matlab 命令行进行一些实验后,我发现我可以在纯 Matlab 中重新创建这个问题(也就是说,独立于我的 C++ 代码及其对引擎 API 的使用)。考虑以下代码:
for i = 1 : 100000
eval(sprintf('x_%d = %d', i, i));
whos
eval(sprintf('clear x_%d', i));
whos
end
在我的 32 位 Windows 笔记本电脑上使用 Matlab R2008B(我知道很古老)执行此代码,循环最终中止并显示错误消息:
当前工作区的变量已经太多了;没有房间 对于“x_65532”。
所以,至少这个过时版本的 Matlab 似乎有 64K 的符号表限制。也许新版(64 位)Matlab 的限制更大——我很想知道其他人得到了什么结果。
然而,更有趣的问题是clear 调用有什么影响以及如何解决它的奇怪行为。这是中止前一点迭代的输出:
x_65530 =
65530
Name Size Bytes Class Attributes
i 1x1 8 double
x_65530 1x1 8 double
Name Size Bytes Class Attributes
i 1x1 8 double
如您所见,whos 输出清楚地表明先前迭代的临时对象已从工作区中删除,并且 clear 似乎按预期工作。尽管如此,符号表显然已经达到了容量。
所以,对于 SO 忠实的人有两个问题:
- 如何解决这个有些随意的限制?也就是说,我的
clear调用应该用什么替换? - 更新和/或 64 位版本的 Matlab 是否改变了这种行为?
【问题讨论】:
-
您能详细介绍一下需要这么多临时变量的用例吗? P.S:循环内的第一个
sprintf不需要eval... -
可在 2011b(32 位)中复制 - 完全相同的错误点。有趣的是,如果我在命令行中定义其他变量或重新运行循环,我不会得到错误(直到我再次在循环中达到该点)。
-
@EitanT:用例:我的 C++ 代码为 matlab 绘图设置动画,在每一帧中发送大量新数据。可能有更好的方法可以做到这一点,但它有效(至少在达到极限之前)。至于评估,你确定吗?我明确地尝试创建一个具有算法选择的唯一名称的变量。跳过 eval 会给我一个未命名的临时字符串,不是吗?
-
@nkjt:很有趣。也许循环上下文有自己的符号表,从属于全局表?我的 C++ 代码失败并没有在 matlab for 循环中执行此操作,顺便说一句 - 所以我可能会污染全局表。当然,所有的猜测......
-
好的,所以不是所有的 TempVar 实例都必须包含类似的信息?我假设所有变量都由同一个“客户端”读取,在这种情况下更新单个变量似乎要好得多。如果你必须坚持变量命名,你可以尝试重新使用变量名,一旦它们被清除。
标签: matlab limits symbol-table