Last active
May 5, 2019 17:26
-
-
Save ggrothendieck/53811e2769d0582407ae to your computer and use it in GitHub Desktop.
Illustrates that a NumericVector is a pointer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @title A NumericVector is Really a Pointer | |
* @author G. Grothendieck completing Michael Meyer's post at https://stat.ethz.ch/pipermail/r-help/2015-August/431645.html | |
* @license GPL (>= 2) | |
* @tags NumericVector pointer | |
* @summary Shows that a NumericVector is a pointer. | |
*/ | |
// To run: library(Rcpp); sourceCpp("leftShift.cpp") | |
#include <Rcpp.h> | |
using namespace Rcpp; | |
// [[Rcpp::export]] | |
NumericVector leftShift(NumericVector x){ | |
int n = x.size(); | |
Rprintf("C++: address of x prior to modification <%p>\n", (SEXP)x); | |
for(int i=0;i<n-1;i++) x[i]=x[i+1]; | |
Rprintf("C++: address of x after modification <%p>\n", (SEXP)x); | |
return x; | |
} | |
// next function is the same except x is a clone of the input | |
// [[Rcpp::export]] | |
NumericVector leftShiftClone(NumericVector x0){ | |
NumericVector x(clone(x0)); | |
int n = x.size(); | |
// the address of x0 will be the same as address of x0 in R | |
// the x addresses will be the same as each other and different from x0 | |
Rprintf("C++: address of x0 <%p>\n", (SEXP)x0); | |
Rprintf("C++: address of x prior to modification <%p>\n", (SEXP)x); | |
for(int i=0;i<n-1;i++) x[i]=x[i+1]; | |
Rprintf("C++: address of x after modification <%p>\n", (SEXP)x); | |
return x; | |
} | |
/*** R | |
library(pryr) | |
######################################################### | |
# x, the input, changes | |
x <- c(1, 2, 3) | |
address(x) # R: address of x prior to calling C++ | |
y <- leftShift(x) | |
address(y) # R: address of output y | |
y | |
address(x) # R: address of x after calling C++ | |
x # the input, x, has changed! | |
######################################################### | |
# x0, the input, is unchanged | |
x0 <- c(1, 2, 3) | |
address(x0) # R: address of x0 prior to calling C++ | |
y0 <- leftShiftClone(x0) | |
address(y0) # R: address of y after calling C++ (same as x in C++) | |
y0 | |
x0 # since leftShiftClone internally cloned x0 (the input), x0 did not change | |
address(x0) # R: address of x0 after calling C++ (unchanged) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also note this discussion of swapping without copying in R.
https://stackoverflow.com/questions/54970202/swap-two-sexp-without-copying/54970808#54970808