Tcl_Obj *消耗了多少内存,我需要删除它吗?

时间:2015-09-12 09:31:01

标签: tcl

std::string cmd = get_itcl_obj_name() + " set_ude_jobname " + name;
Tcl_Obj* cmdobj = Tcl_NewStringObj(cmd.c_str(),-1 );
if(Tcl_EvalObjEx(interp, cmdobj, TCL_EVAL_GLOBAL) == TCL_OK)
{
    return true;
}
else
{
    return false;
}

我有这部分代码被称为数千个时间并且消耗高内存,所以我无法确定是否需要删除此tcl对象指针?

1 个答案:

答案 0 :(得分:1)

A Tcl_Obj指向一个32位系统上24字节长的内存(我没有在64位系统上测量过,但它可能高达48字节,具体取决于方式编译器打包结构)。它还可以指向可以在大小上变化的更多内存; 64位系统上肯定可以使用千兆字节。特别是,值的字符串表示可以挂起,就像列表或字典表示之类的其他东西一样。 (细节内容非常多变。)

所以是的,一旦不再需要它们就应该正确发布!虽然您永远不需要在Tcl语言级别执行此操作(除了偶尔在全局变量上使用unset),但在Tcl C API级别使引用计数管理正确是至关重要的。

在您正在使用的代码的特定情况下,您需要两个 Tcl_IncrRefCount(cmdobj)才能调用Tcl_EvalObjExTcl_DecrRefCount(cmdobj)之后。由于您使用的是C ++,因此辅助RAII类可能会使这更容易。

或者您可以使用Tcl_GlobalEval,这些日子只是相同底层基本函数的包装器,但为您执行Tcl_Obj内存管理。

std::string cmd = get_itcl_obj_name() + " set_ude_jobname " + name;
if (Tcl_GlobalEval(interp, cmd.c_str()) == TCL_OK) {
    return true;
} else {
    return false;
}

(有一些小的性能差异,但它们确实无关紧要。或者如果它们确实如此,我们建议使用Tcl_EvalObjv进行更大幅度的重写,但这是一个更大的变化。也许要做一些Tcl_Obj的缓存,这样Tcl就可以在后端挂起一个字节码编译。所有这些都比你想到的要大得多!)