Ich lerne R und lese gerade dieses Buch . Um sicherzustellen, dass ich das Konzept verstehe, habe ich den folgenden Test durchgeführt, der sich für mich als ziemlich verwirrend herausstellte, und ich würde mich freuen, wenn Sie ihn klären könnten. Hier ist der Test, den ich direkt in der R-Shell vom Terminal aus ausgeführt habe (ohne RStudio oder 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
Können Sie mir sagen, wo mein Fehler liegt und was ich bei diesem Problem falsch verstanden habe?
obj_addr(x[1])
wenn Sie zweimal ausführen, sollten Sie unterschiedliche Ergebnisse erzielen, da jede neue Ganzzahl eine eigene Adresse hat.Antworten:
Jedes R-Objekt ist ein C (Zeiger genannt
SEXP
- auf a) "Multi-Objekt" (struct
). Dies umfasst Informationen (die Rlength
ausführen muss, z. B. die Anzahl der Referenzen - um zu wissen, wann ein Objekt kopiert werden muss - und mehr) über das R-Objekt und auch die tatsächlichen Daten des R-Objekts, auf das wir Zugriff haben.lobstr::obj_addr
Vermutlich gibt die Speicheradresse zurück, auf die aSEXP
zeigt. Dieser Teil des Speichers enthält sowohl die Informationen als auch die Daten des R-Objekts. Innerhalb der R-Umgebung können / müssen wir nicht auf den (Zeiger auf den) Speicher der tatsächlichen Daten in jedem R-Objekt zugreifen.Wie Adam in seiner Antwort feststellt,
[
kopiert die Funktion das n-te Element der im C-Objekt enthaltenen Daten in ein neues C-Objekt und gibt seinenSEXP
Zeiger auf R zurück. Bei jedem[
Aufruf wird ein neues C-Objekt erstellt und an R zurückgegeben.Wir können nicht über R auf die Speicheradresse jedes Elements der tatsächlichen Daten unseres Objekts zugreifen. Wenn wir jedoch ein bisschen herumspielen, können wir die entsprechenden Adressen mit der C api verfolgen:
Eine Funktion zum Abrufen der Adressen:
Und auf unsere Daten anwenden:
Der sukzessive Speicherunterschied zwischen den Datenelementen unseres Objekts entspricht der Größe des
int
Typs:Verwenden der
[
Funktion:Dies könnte eine mehr als notwendige ausführliche Antwort sein und vereinfacht die tatsächlichen technischen Details, bietet aber hoffentlich ein klareres "Gesamtbild".
quelle
Dies ist eine Möglichkeit, es zu betrachten. Ich bin sicher, dass es eine technischere Sichtweise gibt. Denken Sie daran, dass in R fast alles eine Funktion ist. Dies beinhaltet die Extraktionsfunktion ,
[
. Hier ist eine äquivalente Aussage zux[1]
:Sie führen also eine Funktion aus, die einen Wert zurückgibt (Auschecken
?Extract
). Dieser Wert ist eine Ganzzahl. Wenn Sie ausführenobj_addr(x[1])
, wird die Funktion ausgewertetx[1]
und Sie erhalten dann dieobj_addr()
Rückgabe dieser Funktion, nicht die Adresse des ersten Elements des Arrays, das Sie anx
und gebunden habeny
.quelle