我在R函数中有一个Rcpp函数。 R函数生成一些对象(比如一个大的列表)并将其提供给Rcpp函数。在Rcpp函数内部,我处理R对象,将结果加载到许多C ++类。现在R对象变得无用了。我想消灭R对象,为主算法创建一个足够内存的环境。
这个想法是:
// [[Rcpp::export]]
void cppFun(List structuredData)
{
// copy structuredData to C++ classes
// Now I want structuredData gone to save memory
// main algorithms ...
}
/***R
rFun(input)
{
# R creates structuredData from input
cppFun(structuredData)
}
*/
我试着打电话给R" rm()"在C ++中它只能识别R全球环境中的对象名称。例如:
// [[Rcpp::export]]
void cppFun()
{
Language("rm", "globalDat").eval();
Language("gc").eval();
}
/***R
globalDat = 1:10
ls() # shows "globalDat" is created.
cppFun() # shows "globalDat" is no longer in the environment.
ls()
*/
但是,以下情况不起作用:
// [[Rcpp::export]]
void cppFun()
{
Language("rm", "localDat").eval();
Language("gc").eval();
}
/***R
rFun <- function (x)
{
locDat = x
ls() // shows "x" and "locDat" are created
cppFun()
ls()
}
globalDat = 1:10
ls() # shows "globalDat" is created.
rFun(globalDat) # it will print "x","locDat" twice and a warning message: In rm("localDat") : object 'localDat' not found
locDat = globalDat
rFun(globalDat) # this will still remove "locDat" from the global environment.
*/
我是否在正确的目标上?还有更好的办法吗?
谢谢!
想到一个hacky解决方案:
编写一个shell类,包含对所有必需的C ++结构化数据类的引用。
在R函数中,(i)处理输入; (ii)将结构化R数据馈送到Rcpp函数; (iii)在Rcpp函数中,new
一个shell类对象,加载结构化的R数据; (iv)memcpy
shell类指针指向double
(8字节,如果是32位系统,则使用int
); (v)归还double
; (vi)将double
退出R函数。现在结构化的R对象在new
ed C ++ shell对象仍然存在时死亡。调用gc()
进行垃圾回收。
将double
提供给主C ++ / Rcpp函数。 memcpy
这是shell类指针的两倍。 delete
函数返回前的shell类指针。
测试显示上述作品。刚发现&#34;外部指针&#34;或Rcpp::XPtr
是出于类似目的而设计的?
答案 0 :(得分:4)
在 Rcpp 中,沿着这些方向做某事将被称为antipattern或非常适得其反。 为什么这是有问题的 Rcpp 在将 R 对象移动到 C ++时执行浅层复制 ,表示 R 对象与实例化的 C ++ 对象共享它的内存分配。如果您在 C ++ 对象引用它时删除 R 对象,那么您可能会在此过程中遇到麻烦{{{ 3}}可能会发生。
现在,如果您打算从 R 对象执行深层复制到 C ++ 结构,那么这不会像有毒的。执行深层复制时,数据不引用原始 R 对象。但是, 是 Rcpp 的默认架构。
说到这里,我强烈不鼓励在进程中删除对象。如果您确实存在记忆障碍,请尝试“分块”/分割数据,使用数据库执行操作,购买额外的RAM,或等待segmentation fault (segfault)。