后期编辑:重要说明:此处报告的行为似乎仅在RStudio中发生,而不是在R终端中发生。
我的RStudio版本是:1.2.1511。
我试图了解R中的对象何时发生适当的位置更改,或者何时遵循copy-on-modify
语义。
在该示例中,Hadley演示了如何在R中修改对象。他谈到了两种情况:具有单一名称绑定的对象和环境。
我尝试了使用向量v
的示例,但更改了其中一个值后,向量v
的地址没有得到保留。
在向量3
的位置3
上改变值v
之后,v
的存储地址从0x5583a1461fb8
变为0x5583a2c5f608
。
所以我的问题是为什么?这似乎与哈德利的书本范例相矛盾。
v <- c(1, 2, 3)
pryr::address(v)
#> [1] "0x5583a1461fb8"
lobstr::obj_addr(v)
#> [1] "0x5583a1461fb8"
v[[3]] <- 4
pryr::address(v)
#> [1] "0x5583a2c5f608"
lobstr::obj_addr(v)
#> [1] "0x5583a2c5f608"
sessionInfo()
#> R version 3.5.1 (2018-07-02)
#> Platform: x86_64-pc-linux-gnu (64-bit)
#> Running under: Arch Linux
#>
#> Matrix products: default
#> BLAS: /usr/lib/libblas.so.3.8.0
#> LAPACK: /usr/lib/liblapack.so.3.8.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_DK.utf8 LC_COLLATE=en_US.UTF-8
#> [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
#> [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
#> [9] LC_ADDRESS=C LC_TELEPHONE=C
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> loaded via a namespace (and not attached):
#> [1] Rcpp_1.0.1 codetools_0.2-15 digest_0.6.18 rprojroot_1.3-2
#> [5] backports_1.1.2 magrittr_1.5 evaluate_0.12 rlang_0.3.4
#> [9] stringi_1.4.3 pryr_0.1.4 rmarkdown_1.10 lobstr_1.0.1
#> [13] tools_3.5.1 stringr_1.4.0 yaml_2.2.0 compiler_3.5.1
#> [17] htmltools_0.3.6 knitr_1.20
P.S。我使用了pryr
和lobstr
包来查找内存地址。我也尝试使用tracemem()
,但出现此错误:
Error in tracemem(m) :
R was not compiled with support for memory profiling
答案 0 :(得分:2)
如另一个问题所述:
In place modification of matrices in R
问题在于RStudio的“环境”窗格引用了v
。因此v
向量不再是单个名称bound(?)...因此,当我们更改v
时,R需要复制它。
fn <- function() {
v <- c(1, 2, 3)
print(pryr::address(v))
print(lobstr::obj_addr(v))
v[[3]] <- 4
print(pryr::address(v))
print(lobstr::obj_addr(v))
}
fn()
#> [1] "0x55e4acd1b538"
#> [1] "0x55e4acd1b538"
#> [1] "0x55e4acd1b538"
#> [1] "0x55e4acd1b538"