From plummerm at iarc.fr  Thu Apr  7 10:48:37 2016
From: plummerm at iarc.fr (Martyn Plummer)
Date: Thu, 7 Apr 2016 08:48:37 +0000
Subject: [Rd] Assignment operator and deep copy for calling C functions
In-Reply-To: <VI1PR08MB044815D26F1464F2BC630FC3899E0@VI1PR08MB0448.eurprd08.prod.outlook.com>
References: <VI1PR08MB044815D26F1464F2BC630FC3899E0@VI1PR08MB0448.eurprd08.prod.outlook.com>
Message-ID: <1460018916.26865.85.camel@iarc.fr>

This is discussed in the "Writing R Extensions" manual section?5.9.10:
Named objects and copying.

.Call does not copy its arguments and it is not safe to modify them, as
you have found, since multiple symbols may refer to the same object. If
you are going to modify an argument to .Call you should take a deep
copy with "duplicate" first, and your function should return the
modified copy.

It is probably also worth mentioning Rcpp, which provides a friendlier
interface to R than the C API. In Rcpp you use clone() to force a deep
copy.

Martyn ?


On Tue, 2016-04-05 at 15:38 +0000, Thorsten R wrote:
> Hi All,
> 
> i have a problem in understanding what the assignment operator '<-
> '??really is doing.
> If i create two numeric arrays in R and copy one into the other with
> '<-' and
> afterwards change one array by calling a C function, both arrays are
> changed!
> 
> The problem I am facing can easily be seen in the following example:
> (The following R code and the C function is attached and the C
> function can be compiled with R CMD SHLIB test.c.)
> 
> First include the c function:
> ????dyn.load("test.so")
> 
> Let's start with 2 arrays:
> ????a??<- rep(0, 5)
> ????b??<- rep(1, 5)
> 
> Now print the memory addresses:
> ????print(sprintf("a: %s????b: %s", tracemem(a), tracemem(b) ))
> ????[1] "a: <0x29d34e0>????b: <0x29946e0>"
> 
> oky, they are different! Now copy a into b and print again the
> addresses:
> ????b <- a
> ????print(sprintf("a: %s????b: %s", tracemem(a), tracemem(b) ))
> ????[1] "a: <0x29d34e0>????b: <0x29d34e0>"
> 
> Ugh they are the same. If I now call my C function, which writes
> 0,1,2,3,4 into an array of 5 doubles,
> of course 'both' arrays are changed:
> ????.Call("test", b)
> ????print( cbind(a,b) )
> ?????????a b
> ????[1,] 0 0
> ????[2,] 1 1
> ????[3,] 2 2
> ????[4,] 3 3
> ????[5,] 4 4
> 
> 
> If i just change one element of b instead of calling the c function,
> then a full copy of b is made:
> ????a <- rep(0, 5)
> ????b <- rep(1, 5)
> ????print(sprintf("a: %s????b: %s", tracemem(a), tracemem(b) ))
> ????[1] "a: <0x2994b58>????b: <0x2912ff8>"
> 
> ????b <- a
> ????print(sprintf("a: %s????b: %s", tracemem(a), tracemem(b) ))
> ????[1] "a: <0x2994b58>????b: <0x2994b58>"
> 
> ????b[1] <- 5
> ????print(sprintf("a: %s????b: %s", tracemem(a), tracemem(b) ))
> ????"a: <0x2994b58>????b: <0x29134d8>"
> 
> ????print( cbind(a,b) )
> ?????????a b
> ????[1,] 0 5
> ????[2,] 0 0
> ????[3,] 0 0
> ????[4,] 0 0
> ????[5,] 0 0
> 
> 
> So what is happening here? What is the 'right' way to ensure a deep
> copy before using Call?
> I am currently using a for loop and copy every single element.
> 
> Thanks!
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel-----------------------------------------------------------------------
This message and its attachments are strictly confidenti...{{dropped:8}}



[Rd] Assignment operator and deep copy for calling C functions
Martyn Plummer