Я изучаю R и в настоящее время я читаю эту книгу . Чтобы убедиться, что я понимаю концепцию, я провел следующий тест, который оказался довольно запутанным для меня, и я был бы признателен, если бы вы могли уточнить его. Вот тест, который я запускал непосредственно в R-оболочке с терминала (не используя RStudio или 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
Не могли бы вы сказать мне, где моя ошибка и что я неправильно понял в этой проблеме?
obj_addr(x[1])
должен давать разные результаты, поскольку каждое новое целое число будет иметь свой собственный адрес.Ответы:
Любой объект R является C (указатель называется
SEXP
на) "multi-object" (struct
). Это включает в себя информацию (которую R должен использовать, напримерlength
, количество ссылок - чтобы узнать, когда копировать объект - и более) об объекте R, а также фактические данные объекта R, к которым у нас есть доступ.lobstr::obj_addr
предположительно, возвращает адрес памяти, на которыйSEXP
указывает точка. Эта часть памяти содержит как информацию об объекте R, так и данные о нем. Из среды R мы не можем / не должны обращаться к (указателю на) памяти фактических данных в каждом объекте R.Как отмечает Адам в своем ответе, функция
[
копирует n-й элемент данных, содержащихся в объекте C, в новый объект C и возвращает егоSEXP
указатель на R. При каждом[
вызове создается новый объект C и возвращается в R.Мы не можем получить доступ к адресу памяти каждого элемента фактических данных нашего объекта через R. Но немного поиграв, мы можем отследить соответствующие адреса, используя C api:
Функция для получения адресов:
И применяя к нашим данным:
Последовательная разница в памяти между элементами данных нашего объекта равна размеру
int
типа:Используя
[
функцию:Это могло бы быть более чем необходимым подробным ответом и упрощенным с точки зрения фактических технических особенностей, но, мы надеемся, предлагает более ясную "большую" картину.
источник
Это один из способов взглянуть на это. Я уверен, что есть более технический взгляд. Помните, что в R почти все является функцией. Это включает в себя функцию извлечения
[
. Вот эквивалентное утверждение дляx[1]
:Итак, вы выполняете функцию, которая возвращает значение (зацените
?Extract
). Это значение является целым числом. Когда вы запускаетеobj_addr(x[1])
, он оценивает функцию,x[1]
а затем выдаетobj_addr()
возврат этой функции, а не адрес первого элемента массива, который вы связали с обоимиx
иy
.источник