Saya belajar R dan saat ini saya sedang membaca buku ini . Untuk memastikan saya memahami konsepnya, saya menjalankan tes berikut yang ternyata cukup membingungkan bagi saya dan saya akan menghargai jika Anda bisa menjelaskannya. Inilah tesnya, yang saya jalankan langsung di shell R dari terminal (tidak menggunakan RStudio atau Emacs ESS).
> library(lobstr)
>
> x <- c(1500,2400,8800)
> y <- x
> ### So the following two lines must return the same memory address
> obj_addr(x)
[1] "0xb23bc50"
> obj_addr(y)
[1] "0xb23bc50"
> ### So as I expected, indeed both x and y point to the same memory
> ### location: 0xb23bc50
>
>
>
> ### Now let's check that each element can be referenced by the same
> ### memory address either by using x or y
> x[1]
[1] 1500
> y[1]
[1] 1500
> obj_addr(x[1])
[1] "0xc194858"
> obj_addr(y[1])
[1] "0xc17db88"
> ### And here is exactly what I don't understand: x and y point
> ### to the same memory address, so the same must be true for
> ### x[1] and y[1]. So how come I obtain two different memory
> ### addresses for the same element of the same vector?
>
>
>
> x[2]
[1] 2400
> y[2]
[1] 2400
> obj_addr(x[2])
[1] "0xc15eca0"
> obj_addr(y[2])
[1] "0xc145d30"
> ### Same problem!
>
>
>
> x[3]
[1] 8800
> y[3]
[1] 8800
> obj_addr(x[3])
[1] "0xc10e9b0"
> obj_addr(y[3])
[1] "0xc0f78e8"
> ### Again the same problem: different memory addresses
Bisakah Anda memberi tahu saya di mana kesalahan saya dan apa yang saya salah pahami dalam masalah ini?
obj_addr(x[1])
dua kali akan memberi Anda hasil yang berbeda, karena setiap integer baru akan memiliki alamatnya sendiri.Jawaban:
Setiap objek R adalah C (pointer -called
SEXP
- to a) "multi-object" (struct
). Ini termasuk informasi (yang perlu dioperasikan R, mis.length
, Jumlah referensi - untuk mengetahui kapan harus menyalin suatu objek - dan lebih banyak lagi) tentang objek R dan, juga, data aktual dari objek R yang kita miliki aksesnya.lobstr::obj_addr
, mungkin, mengembalikan alamat memori yangSEXP
ditunjuk. Bagian memori itu berisi informasi tentang dan data objek R. Dari dalam lingkungan R kita tidak bisa / tidak perlu mengakses (pointer ke) memori data aktual di setiap objek R.Seperti yang dicatat Adam dalam jawabannya, fungsi ini
[
menyalin elemen ke-n dari data yang terdapat dalam objek C ke objek C baru dan mengembalikanSEXP
penunjuknya ke R. Setiap kali[
dipanggil, objek C baru dibuat dan dikembalikan ke R.Kami tidak dapat mengakses alamat memori dari setiap elemen data aktual objek kami melalui R. Namun dengan sedikit memutar, kami dapat melacak masing-masing alamat menggunakan api C:
Fungsi untuk mendapatkan alamat:
Dan berlaku untuk data kami:
Perbedaan memori berurutan antara elemen data objek kami sama dengan ukuran
int
jenis:Menggunakan
[
fungsi:Ini mungkin jawaban yang lebih luas dari yang diperlukan dan sederhana dalam hal teknis sebenarnya, tetapi, semoga, menawarkan gambaran "besar" yang lebih jelas.
sumber
Ini adalah salah satu cara untuk melihatnya. Saya yakin ada pandangan yang lebih teknis. Ingatlah bahwa dalam R, hampir semuanya adalah fungsi. Ini termasuk fungsi ekstrak
[
,. Berikut ini adalah pernyataan yang setara untukx[1]
:Jadi apa yang Anda lakukan adalah menjalankan fungsi yang mengembalikan nilai (periksa
?Extract
). Nilai itu adalah bilangan bulat. Ketika Anda menjalankanobj_addr(x[1])
, itu mengevaluasi fungsix[1]
dan kemudian memberi Andaobj_addr()
kembali fungsi itu, bukan alamat elemen pertama dari array yang terikat ke keduanyax
dany
.sumber