From thorstenr_42 at hotmail.de  Tue Apr  5 17:38:05 2016
From: thorstenr_42 at hotmail.de (Thorsten R)
Date: Tue, 5 Apr 2016 15:38:05 +0000
Subject: [Rd] Assignment operator and deep copy for calling C functions
Message-ID: <VI1PR08MB044815D26F1464F2BC630FC3899E0@VI1PR08MB0448.eurprd08.prod.outlook.com>

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!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.c
Type: text/x-csrc
Size: 277 bytes
Desc: test.c
URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20160405/12cf70a5/attachment.bin>


[Rd] Assignment operator and deep copy for calling C functions
Thorsten R