Uczę się języka R i obecnie czytam tę książkę . Aby upewnić się, że rozumiem tę koncepcję, przeprowadziłem następujący test, który okazał się dla mnie dość mylący i byłbym wdzięczny za wyjaśnienie. Oto test, który uruchomiłem bezpośrednio w powłoce R z terminala (nie używając RStudio lub 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
Czy możesz mi powiedzieć, gdzie jest mój błąd i co źle zrozumiałem w tym problemie?
obj_addr(x[1])
dwukrotne uruchomienie powinno dać różne wyniki, ponieważ każda nowa liczba całkowita będzie miała swój własny adres.Odpowiedzi:
Każdy obiekt R jest C (wywołany wskaźnikiem
SEXP
- na a) „multi-object” (struct
). Obejmuje to informacje (które R musi operować, np.length
Liczbę referencji - aby wiedzieć, kiedy skopiować obiekt - i więcej) o obiekcie R, a także rzeczywiste dane obiektu R, do którego mamy dostęp.lobstr::obj_addr
, prawdopodobnie zwraca adres pamięci, na którySEXP
wskazuje. Ta część pamięci zawiera zarówno informacje o obiekcie R, jak i dane. Ze środowiska R nie możemy / nie musimy uzyskiwać dostępu do (rzeczywistej) pamięci rzeczywistych danych w każdym obiekcie R.Jak zauważa Adam w swojej odpowiedzi, funkcja
[
kopiuje n-ty element danych zawartych w obiekcie C do nowego obiektu C i zwracaSEXP
wskaźnik do R. Za każdym razem, gdy[
jest wywoływany, nowy obiekt C jest tworzony i zwracany do R.Nie możemy uzyskać dostępu do adresu pamięci każdego elementu rzeczywistych danych naszego obiektu przez R. Ale bawiąc się trochę, możemy prześledzić odpowiednie adresy za pomocą interfejsu API:
Funkcja uzyskiwania adresów:
A zastosowanie do naszych danych:
Kolejna różnica w pamięci między elementami danych naszego obiektu jest równa rozmiarowi
int
typu:Korzystanie z
[
funkcji:To może być bardziej niż potrzebna obszerna odpowiedź i jest uproszczona w odniesieniu do faktycznych szczegółów technicznych, ale, mam nadzieję, oferuje wyraźniejszy „duży” obraz.
źródło
To jeden ze sposobów, aby na to spojrzeć. Jestem pewien, że jest bardziej techniczny pogląd. Pamiętaj, że w R prawie wszystko jest funkcją. Obejmuje funkcję wyciągu,
[
. Oto oświadczenie równoważne zx[1]
:Więc uruchamiasz funkcję, która zwraca wartość (sprawdź
?Extract
). Ta wartość jest liczbą całkowitą. Podczas uruchamianiaobj_addr(x[1])
ocenia funkcję,x[1]
a następnieobj_addr()
zwraca jej zwrot, a nie adres pierwszego elementu tablicy, do którego przypisano jednox
i drugiey
.źródło