在C ++函数环境中删除输入R对象

时间:2017-08-17 22:24:53

标签: c++ r rcpp

我在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解决方案:

  1. 编写一个shell类,包含对所有必需的C ++结构化数据类的引用。

  2. 在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()进行垃圾回收。

  3. double提供给主C ++ / Rcpp函数。 memcpy这是shell类指针的两倍。 delete函数返回前的shell类指针。

  4. 测试显示上述作品。刚发现&#34;外部指针&#34;或Rcpp::XPtr是出于类似目的而设计的?

1 个答案:

答案 0 :(得分:4)

Rcpp 中,沿着这些方向做某事将被称为antipattern或非常适得其反。 为什么这是有问题的 Rcpp 在将 R 对象移动到 C ++时执行浅层复制 ,表示 R 对象与实例化的 C ++ 对象共享它的内存分配。如果您在 C ++ 对象引用它时删除 R 对象,那么您可能会在此过程中遇到麻烦{{{ 3}}可能会发生。

现在,如果您打算从 R 对象执行深层复制 C ++ 结构,那么这不会像有毒的。执行深层复制时,数据引用原始 R 对象。但是, Rcpp 的默认架构。

说到这里,我强烈不鼓励在进程中删除对象。如果您确实存在记忆障碍,请尝试“分块”/分割数据,使用数据库执行操作,购买额外的RAM,或等待segmentation fault (segfault)