使用 Rcpp 和 R 时,我观察到以下行为,但目前我不明白。考虑以下用 Rcpp 编写的简单函数
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix hadamard_product(NumericMatrix & X, NumericMatrix & Y){
unsigned int ncol = X.ncol();
unsigned int nrow = X.nrow();
int counter = 0;
for (unsigned int j=0; j<ncol; j++) {
for (unsigned int i=0; i<nrow; i++) {
X[counter++] *= Y(i, j);
}
}
return X;
}
这只是返回两个矩阵的按分量乘积。现在我知道这个函数的参数是通过引用传递的,即调用
M <- matrix(rnorm(4), ncol = 2)
N <- matrix(rnorm(4), ncol = 2)
M_copy <- M
hadamard_product(M, N)
会覆盖原来的M。但是,它也会覆盖M_copy,这是我不明白的。我以为M_copy <- M
制作对象 M 的副本并将其保存在内存中的某个位置,而不是此赋值将 M_copy 指向 M,这将是执行时的行为
x <- 1
y <- x
x <- 2
例如。这不会改变 y,而只会改变 x。
那么为什么会出现上述行为呢?
最佳答案
不,R 不会立即进行复制,只有在必要时才进行复制,即修改时复制:
x <- 1
tracemem(x)
#[1] "<0000000009A57D78>"
y <- x
tracemem(x)
#[1] "<0000000009A57D78>"
x <- 2
tracemem(x)
#[1] "<00000000099E9900>"
由于您通过 R 外部的引用修改 M,R 无法知道副本是必要的。如果您想确保创建副本,可以使用data.table::copy
。或者避免 C++ 代码中的副作用,例如,在其中进行深层复制(通过使用clone
)。
关于Rcpp 和 R : pass by reference,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45815822/