Search code examples
rfor-loopmemorypryr

Why is the address of a loop variable changing when using it?


Program 1:

 library(pryr)

 for (x in 1:3) {
     print(c(address(x), refs(x)))
 }

Output e.g.:

[1] "0x7a6a6c8" "1"        
[1] "0x7a6a6c8" "1"        
[1] "0x7a6a6c8" "1"

Program 2:

library(pryr)

for (x in 1:3) {
  print(c(address(x), refs(x)))
  print(x)
}

Output e.g.:

[1] "0x7ae0298" "1"        
[1] 1
[1] "0x7ae88c8" "1"        
[1] 2
[1] "0x7af2668" "1"        
[1] 3

Obviously the value of x is changing in Program 2, but why is the adress changing too? Can this lead to memory leaks when having a for loop running about 500,000,000 times while the gc is not called during the loop?


Solution

  • Having print(x) at the end of the loop marks it as multi-reference, as @alexis_laz mentioned. Since R is a dynamic language, this can happen easily. To test the effects of this, we can print the output of refs(x), print(x), refs(x):

    for (x in 1:3) {
      print(refs(x))
      print(x)
      print(refs(x)); cat("\n")
    }
    

    Output:

    [1] 1
    [1] 1
    [1] 2
    
    [1] 1
    [1] 2
    [1] 2
    
    [1] 1
    [1] 3
    [1] 2