C++ 从Rcpp函数接收结果后会话崩溃

C++ 从Rcpp函数接收结果后会话崩溃,c++,r,rcpp,C++,R,Rcpp,下面的代码编译和执行正确,但每次我运行它时,我的R会话在完成后不久就会出现致命错误。我正在运行R版本3.3.2和Rtools 3.3 有什么我错过的吗?我怎样才能追踪导致坠机的原因 #include<Rcpp.h> using namespace Rcpp; NumericMatrix dupCheckRcpp(NumericMatrix x) { int nrow, ncol; int i, j, k, m, n; bool flag; Numer

下面的代码编译和执行正确,但每次我运行它时,我的R会话在完成后不久就会出现致命错误。我正在运行R版本3.3.2和Rtools 3.3

有什么我错过的吗?我怎样才能追踪导致坠机的原因

#include<Rcpp.h>
using namespace Rcpp;

NumericMatrix dupCheckRcpp(NumericMatrix x) {
    int nrow, ncol;
    int i, j, k, m, n;
    bool flag;
    NumericMatrix dupMat(300,ncol);

    n = 0;
    nrow = 0; ncol = 0;
    nrow = x.nrow();
    ncol = x.ncol();

    for (i = 0; i < nrow - 1 ; ++i) {
        for (j = i + 1; j < nrow; ++j) {
            flag = TRUE;
            for (k = 0; k < ncol; ++k) {
                if (x(i,k) != x(j,k)) {
                    flag = FALSE;
                    break;
                }
            }
            if (flag == TRUE) {
                for (m = 0; m < ncol; ++m) {
                    dupMat(n,m) = x(i,m);
                }
                n = n + 1;
            }
        }
    }
    return dupMat;
}
#包括
使用名称空间Rcpp;
NumericMatrix dupCheckRcpp(NumericMatrix x){
int nrow,ncol;
int i,j,k,m,n;
布尔旗;
数字矩阵dupMat(300,ncol);
n=0;
nrow=0;ncol=0;
nrow=x.nrow();
ncol=x.ncol();
对于(i=0;i
您的代码存在一些问题。我们首先了解结果矩阵是如何定义的,使用
bool
,然后详细说明矩阵子集导致的未定义行为(UB)问题


以下定义:

NumericMatrix dupMat(300, ncol);
有两个问题:

  • 它位于初始化
    ncol
    之前
  • 假设
    x
    矩阵的
    nrow
    固定为300
  • dupMat
    的实例化移动到
    ncol
    nrow
    初始化之后。或者,移动它直到知道重复行的数量

    nrow = x.nrow();
    ncol = x.ncol();
    
    Rcpp::NumericMatrix dupMat(nrow, ncol); 
    

    <> > BoOL C++中的值是用小写的。

    也就是说,在设置
    flag
    变量的值时,使用
    true
    代替
    true
    false
    代替
    false


    有三种方法可以访问
    numerimatrix
    中的单个元素,但是,我们将只关注其中两种使用
    i,j
    索引的方法

    • (i,j)
      :以这种方式访问元素将放弃边界检查和后续异常标志,如果该点不在范围内,则会发出警告。本质上,这种访问方法会导致UB,因为
      n=n+1
      很容易超出行索引。可能是UB在稍后RStudio或R运行后台任务时造成了严重破坏,导致崩溃发生
    • .at(i,j)
      :这是首选方法,因为它提供边界检查并抛出一个漂亮的异常,例如
    dupCheckRcpp(a)中出错:索引超出范围

    由以下代码段触发:

    if (flag == true) {
        for (m = 0; m < ncol; ++m) {
            Rcpp::Rcout << "dupMat (" << n << ","<< m << ")" << std::endl <<
                "x (" << i << ","<< m << ")" << std::endl;
            dupMat.at(n, m) = x.at(i, m);
        }
        n = n + 1; // able to exceed nrow.
    }
    
    if(标志==true){
    对于(m=0;mRcpp::Rcout您的代码存在一些问题。我们首先了解如何定义结果矩阵,使用
    bool
    ,然后详细说明矩阵子集导致的未定义行为(UB)问题


    以下定义:

    NumericMatrix dupMat(300, ncol);
    
    有两个问题:

  • 它位于初始化
    ncol
    之前
  • 假设
    x
    矩阵的
    nrow
    固定为300
  • dupMat
    的实例化移动到初始化
    ncol
    nrow
    之后。或者,将其移动到知道重复行的数量之后

    nrow = x.nrow();
    ncol = x.ncol();
    
    Rcpp::NumericMatrix dupMat(nrow, ncol); 
    

    <> > BoOL C++中的值是用小写的。

    也就是说,在设置
    flag
    变量的值时,使用
    true
    代替
    true
    false
    代替
    false


    有三种方法可以访问
    numerimatrix
    中的单个元素,但是,我们将只关注其中两种使用
    i,j
    索引的方法

    • (i,j)
      :以这种方式访问元素会放弃边界检查和随后的异常标志,如果点不在范围内则会发出警告。本质上,这种访问方法会导致UB,因为
      n=n+1
      很容易超出行索引。当RStudio或R运行backgr时,UB可能会在稍后点造成严重破坏导致崩溃发生的错误任务
    • .at(i,j)
      :这是首选方法,因为它提供边界检查并抛出一个漂亮的异常,例如
    dupCheckRcpp(a)中出错:索引超出范围

    由以下代码段触发:

    if (flag == true) {
        for (m = 0; m < ncol; ++m) {
            Rcpp::Rcout << "dupMat (" << n << ","<< m << ")" << std::endl <<
                "x (" << i << ","<< m << ")" << std::endl;
            dupMat.at(n, m) = x.at(i, m);
        }
        n = n + 1; // able to exceed nrow.
    }
    
    if(标志==true){
    对于(m=0;mRcpp::Rcout未显示的代码的目标是检查1000 x 245矩阵中的向量是否重复。这段代码将整个矩阵提取为仅重复的行(~100-200),以加快检查速度。R duplicated()函数是把矩阵裁剪成重复的简单方法,但它是超低的。我怀疑可能有内置的C++函数使用向量更快地完成这一任务,但是我需要一些快速和肮脏的东西,我可以马上实现,所以我使用蛮力循环。再次感谢。s、 创建一个只包含重复行的矩阵,然后作为列表返回?在列表中搜索会更快吗?目前我正在使用row.names函数来加速测试向量和重复矩阵之间的比较。速度非常快:dupFlag 0我开始实现上面的Rcpp代码,但实现了它本质上是低效的。我将完整矩阵发送给Rcpp,将其提取为重复的矩阵,然后在R中对照它检查向量。为什么不将向量和完整矩阵传递给Rcpp,循环一次,检查它是否重复,然后返回标志?在另一个问题中,我提出了一个更好的方法。将指针传递到矩阵rix和