Возврат Nullable <NumericMatrix>из R cpp в R приводит к ошибке segfault - PullRequest
1 голос
/ 16 июня 2020

Используя R cpp, я написал функцию C ++, которая возвращает «Nullable ». Повторный вызов этой функции из R приводит к сбою моего сеанса R на моем компьютере windows и приводит к ошибке segfault, когда я запускаю его на сервере Linux.

Сам NumericMatrix генерируется другой функцией C ++ и затем «оборачивается» в «Nullable `. Кажется, что ошибка возникает только тогда, когда внутри функции C ++ выполняется еще какое-то вычисление, прежде чем значение возвращается в R. Сама ошибка, похоже, возникает, когда R пытается получить доступ к возвращаемому объекту. Ошибка возникает не каждый раз при вызове функции C ++. Но если я назову его несколько раз, Cra sh почти наверняка.

Вот небольшой код, который, когда я использую CPP, почти каждый раз вылетает:

#include <Rcpp.h>
using namespace Rcpp;


NumericMatrix fun() {
  NumericMatrix m (10, 10);
  std::fill(m.begin(), m.end(), 42);
  return m;
}

int otherCall() {
  NumericVector v(1000);
  std::fill(v.begin(), v.end(), 7);
  return v.length();
}

// [[Rcpp::export]]
Nullable<NumericMatrix> returnNullableObject(int num_it) {
  Nullable<NumericMatrix> object = R_NilValue;

  object = Nullable<NumericMatrix>(fun());

  for (int i = 0; i < num_it; i++) {
    otherCall();
  }

  return object;
}


/*** R
test <- function(n) {
  val <- returnNullableObject(1000L)
  is.matrix(val)
}

for (i in seq_len(100L)) test()

*/

Am Я неправильно использую класс Nullable? Вылетает на R 3.6.1, а также на R 4.0.1

> devtools::session_info()
- Session info ------------------------------------------------------------------------------------------------------------------------------------------------
 setting  value                       
 version  R version 4.0.1 (2020-06-06)
 os       Windows 10 x64              
 system   x86_64, mingw32             
 ui       RStudio                     
 language (EN)                        
 collate  German_Germany.1252         
 ctype    German_Germany.1252         
 tz       Europe/Berlin               
 date     2020-06-16                  

- Packages ----------------------------------------------------------------------------------------------------------------------------------------------------
 package     * version date       lib source        
 assertthat    0.2.1   2019-03-21 [1] CRAN (R 4.0.0)
 backports     1.1.7   2020-05-13 [1] CRAN (R 4.0.0)
 callr         3.4.3   2020-03-28 [1] CRAN (R 4.0.0)
 cli           2.0.2   2020-02-28 [1] CRAN (R 4.0.0)
 crayon        1.3.4   2017-09-16 [1] CRAN (R 4.0.0)
 desc          1.2.0   2018-05-01 [1] CRAN (R 4.0.0)
 devtools      2.3.0   2020-04-10 [1] CRAN (R 4.0.0)
 digest        0.6.25  2020-02-23 [1] CRAN (R 4.0.0)
 ellipsis      0.3.1   2020-05-15 [1] CRAN (R 4.0.0)
 fansi         0.4.1   2020-01-08 [1] CRAN (R 4.0.0)
 fs            1.4.1   2020-04-04 [1] CRAN (R 4.0.0)
 glue          1.4.1   2020-05-13 [1] CRAN (R 4.0.0)
 lattice       0.20-41 2020-04-02 [1] CRAN (R 4.0.1)
 magrittr      1.5     2014-11-22 [1] CRAN (R 4.0.0)
 Matrix        1.2-18  2019-11-27 [1] CRAN (R 4.0.1)
 memoise       1.1.0   2017-04-21 [1] CRAN (R 4.0.0)
 pkgbuild      1.0.8   2020-05-07 [1] CRAN (R 4.0.0)
 pkgload       1.1.0   2020-05-29 [1] CRAN (R 4.0.0)
 prettyunits   1.1.1   2020-01-24 [1] CRAN (R 4.0.0)
 processx      3.4.2   2020-02-09 [1] CRAN (R 4.0.0)
 ps            1.3.3   2020-05-08 [1] CRAN (R 4.0.0)
 R6            2.4.1   2019-11-12 [1] CRAN (R 4.0.0)
 remotes       2.1.1   2020-02-15 [1] CRAN (R 4.0.0)
 rlang         0.4.6   2020-05-02 [1] CRAN (R 4.0.0)
 rprojroot     1.3-2   2018-01-03 [1] CRAN (R 4.0.0)
 rstudioapi    0.11    2020-02-07 [1] CRAN (R 4.0.0)
 sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 4.0.0)
 testthat      2.3.2   2020-03-02 [1] CRAN (R 4.0.0)
 usethis       1.6.1   2020-04-29 [1] CRAN (R 4.0.0)
 withr         2.2.0   2020-04-20 [1] CRAN (R 4.0.0)

1 Ответ

1 голос
/ 17 июня 2020

Короткий ответ: используйте Nullable<> только для ввода функций и ничего больше. Замена Nullable<> на RObject в приведенном выше примере устраняет проблему:

RObject returnNullableObject(int num_it) {
  RObject object = R_NilValue;

  object = fun();

  for (int i = 0; i < num_it; i++) {
    otherCall();
  }

  return object;
}

Спасибо, Дирк за ваши комментарии и пояснения относительно предполагаемого использования Nullable<>!

...