Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

store and retrieve matrices in memory using xptr

I would like to be able to store a matrix created in R in memory and return the pointer. And then later use the pointer to fetch back the matrix from memory. I am running R version 3.0.1 (2013-05-16) -- "Good Sport" on Ubuntu 13.01 and Rcpp version "0.10.6". I have tried ...

// [[Rcpp::export]]
SEXP writeMemObject(NumericMatrix mat)
{
  XPtr<NumericMatrix> ptr(&mat, true);
  return ptr;
}

// [[Rcpp::export]]
NumericMatrix getMemObject(SEXP ptr)
{
  XPtr<NumericMatrix> out(ptr);
  return wrap(out);
}

# This returns a pointer
x <- writeMemObject(matrix(1.0))

But this fails and crashes R when I try again

getMemObject(x)
Error: not compatible with REALSXP
like image 699
CuriousGeorge Avatar asked Jan 16 '14 05:01

CuriousGeorge


1 Answers

The pointer you feed to XPtr here is the address of a variable that is local to writeMemObject. Quite naturally you have undefined behavior.

Also, external pointers are typically used for things that are not R objects, and a NumericMatrix is an R object, so that looks wrong.

If however, for some reason you really want an external pointer to a NumericMatrix then you could do something like this:

#include <Rcpp.h>
using namespace Rcpp ;

// [[Rcpp::export]]
SEXP writeMemObject(NumericMatrix mat){
  XPtr<NumericMatrix> ptr( new NumericMatrix(mat), true);
  return ptr;
}

// [[Rcpp::export]]
NumericMatrix getMemObject(SEXP ptr){
  XPtr<NumericMatrix> out(ptr);
  return *out ;
}

So the pointer created by new outlives the scope of the writeMemObject function.

Also, please see the changes in getMemObject, in your version you had:

XPtr<NumericMatrix> out(ptr);
return wrap(out);

You are not dereferencing the pointer, wrap would just be an identity and return the external pointer rather than the pointee I guess you were looking for.

like image 148
Romain Francois Avatar answered Oct 26 '22 11:10

Romain Francois