【问题标题】:Protection stack overflow with the C interface for R使用 R 的 C 接口保护堆栈溢出
【发布时间】:2021-12-23 03:21:22
【问题描述】:

我目前正在为 3D 中的 Delaunay 和 Voronoï tessellations 编写 R 包。大部分实现都是用 C 语言完成的(在 Qhull 库的帮助下)。

在大量点 (> 10000) 上运行 Delaunay 三角剖分时,我收到此错误:

错误:protect():保护堆栈溢出

在我的 C 代码中,我在函数末尾运行 UNPROTECT,只运行一次。我想知道:如果我将代码分成块,运行UNPROTECT 多次而不是一次(例如每次我达到1000 PROTECT),它会改变什么吗?保护次数是否有已知限制?

【问题讨论】:

  • 一般来说,建议每次退出暴露给 R 用户的函数时运行 UNPROTECT,即使从 C 中退出使用 R 的 C 类型 (SEXP) 的函数时也是如此。我相信源代码中定义了 10000 常量以避免内存溢出,但我想它在现代计算机上被大大低估了。也许向R-package-devel提出这个问题会带来更好的收益。您还可以将所有类型转换为 C 类型,并且只将最终结果写入 SEXP,从而避免一起保护。
  • 您对“Voronoï”的拼写让我意识到我一直误读这个名字(以及 Delaunay 的)。

标签: r c stack-overflow


【解决方案1】:

我终于删除了for循环中的PROTECTs:

  PROTECT(R_vertices = allocVector(VECSXP, nsites));
  PROTECT(vnames = allocVector(STRSXP, nsites));
  nprotect += 2;
  for(unsigned i = 0; i < nsites; i++) {
    SEXP vertex = SiteSXP(vertices[i], dim);
    //    SEXP vertex;
    //    PROTECT(vertex = SiteSXP(vertices[i], dim));
    //    nprotect++;
    SET_VECTOR_ELT(R_vertices, i, vertex);
    SET_STRING_ELT(vnames, i, Rf_asChar(VECTOR_ELT(vertex, 0)));
  }
  setAttrib(R_vertices, R_NamesSymbol, vnames);

似乎没有必要。最后我没有输出vertexs,我只把它们存储在R_vertices中。

【讨论】:

    猜你喜欢
    • 2014-07-03
    • 2016-06-30
    • 2023-04-07
    • 1970-01-01
    • 2015-12-25
    • 2012-12-20
    • 2011-03-02
    • 2014-01-17
    相关资源
    最近更新 更多