Skip to content

Best Practise

2 messages · Tom McCallum, Seth Falcon

#
Hello,


Just a quick question on best practise.  I am converting quite a bit of  
legacy C code into R packages and have the following situation:

(1) Legacy object with a double* array in, all over code so don't want to  
change any more than I have to.

(2) Do something like:
	SEXP arrayToPassToR;
	PROTECT( arrayToPassToR = allocVector( REALSXP, n ) );
	for(i=0; i < n; i++) {
		REAL(arrayToPassToR)[i] = oldCarray[i];   <----  very slow way to copy  
data, can I use memcpy/pointer assignment here to remove the loop without  
running into garbage collector?
	}
	UNPROTECT( arrayToPassToR );
	SEXP returnValueFromR;
(3) Have made it to call back to an R function which returns a new /  
different SEXP double array.
	returnValueFromR = Test_tryEval(...);
(4) Copy back to oldCArray
	for(i=0; i < n; i++) {
		oldCarray[i] = REAL(returnValueFromR)[i]; <--- can I use memcpy/pointer  
assignment here to remove loop?
	}
	UNPROTECT(1);

I have done the long winded copy as I am a bit paranoid about the garbage  
collection.  My question is is it legitimate to do the following

	double* oldCArray = REAL(arrayToPassToR);
	UNPROTECT(1); // where the 1 would remove protection from arrayToPassToR  
and potential garbage collection
	-- assume arrayToPassToR was garbage collected by R --
	Rprintf("%f", oldCArray[0]);

because if arrayToPassToR is garbage collected then oldCArray will cause a  
SEGFAULT when it is accessed afterwards, won't it?

Many thanks

Tom
#
Tom McCallum <termcc at googlemail.com> writes:
You can use memcpy and that should be no different semantically from
the loop.  You cannot reassign the pointer.

Perhaps it is possible to refactor the part of your legacy code that
allocates the vector to begin with?  Then you can use R's allocVector
and send the pointer to the alloc'd vector off to your code.
Depending on how you will use oldCarray, you may not need a copy at
all.  If you have a function that takes a double* then you can pass in
REAL(returnValueFromR).
If you UNPROTECT arrayToPassToR, then the next time R's gc runs
oldCArray will be invalid.

It isn't clear to me from your post what exactly you are trying to do
(and your subject line is confusing, this isn't a best practice
question IMO, but a how do I use R objects in C question).

Perhaps the above hints will get you going.  I would recommend reading
over the relevant sections of the Writing R Extensions manual and the
R internals manual.

+ seth