Skip to content
Prev 54360 / 63421 Next

Array changing address unexpectedly

A simpler version with annotation:

library(pryr)

data <- 1:5          # new allocation, referenced from one variable

add <- address(data)

data[1] <- 6L        # only one reference; don't need to duplicate

add == address(data) # TRUE

print(data)          # inside the print call the local variable also references
                      # the object, so there are two references

data[1] <- 7L        # there have been two references to the object, so need
                      # to duplicate

add == address(data) # FALSE

R objects are supposed to be immutable, so conceptually
assignments create a new object. If R is sure it is safe to do
so, it will avoid making a copy and re-use the original
object. In the first assignment there is only one reference to
the object, the variable data, and it is safe to re-use the
object, so the address of the new value of `data` is the same as
the address of the old value. It would not be safe to do this if
the assignment happened inside print(), since there are then two
references -- the original variable and the local variable for
the argument. R currently doesn't have enough information to know
that there is only one reference after the call to print()
returns, so it has to be safe and make a copy, and the new value
has a different address than the old one. R may be able to be
less conservative in the future, but for now it cannot.

[As an exercise you can try to work out why the calls to
address() don't play a role in this.]

As a rule you shouldn't need to worry about addresses, and R might
make changes in the future that would: cause the address in this
version of the example to change on the first assignments; cause the
address on the second assignment to not change; cause the information
provided by pryr to be inaccurate or misleading; result in the use of
a tool like pryr::address to change the internal structure of the
object.

Best,

luke
On Sun, 12 Nov 2017, lille stor wrote: