Любой объект R является C (указатель называется SEXP
- a) "мультиобъектом" (struct
). Это включает в себя информацию (которую R должен использовать, например, length
, количество ссылок - чтобы знать, когда копировать объект - и более) об объекте R, а также фактические данные объекта R, к которым у нас есть доступ ,
lobstr::obj_addr
, предположительно, возвращает адрес памяти, на который указывает SEXP
. Эта часть памяти содержит информацию о и данных объекта R. Из среды R нам не нужно / не нужно обращаться к (указателю) памяти фактических данных в каждом объекте R.
Как отмечает Адам в своем ответе, функция [
копирует n-й элемент данных, содержащихся в объекте C, в новый объект C и возвращает его указатель SEXP
на R. Каждый раз, когда вызывается [
, новый C объект создан и возвращен в R.
Мы не можем получить доступ к адресу памяти каждого элемента фактических данных нашего объекта через R. Но, немного поиграв, мы можем отследить соответствующие адреса, используя C api:
Функция для получения адресов:
ff = inline::cfunction(sig = c(x = "integer"), body = '
Rprintf("SEXP @ %p\\n", x);
Rprintf("first element of SEXP actual data @ %p\\n", INTEGER(x));
for(int i = 0; i < LENGTH(x); i++)
Rprintf("<%d> @ %p\\n", INTEGER(x)[i], INTEGER(x) + i);
return(R_NilValue);
')
И применение к нашим данным:
x = c(1500L, 2400L, 8800L) #converted to "integer" for convenience
y = x
lobstr::obj_addr(x)
#[1] "0x1d1c0598"
lobstr::obj_addr(y)
#[1] "0x1d1c0598"
ff(x)
#SEXP @ 0x1d1c0598
#first element of SEXP actual data @ 0x1d1c05c8
#<1500> @ 0x1d1c05c8
#<2400> @ 0x1d1c05cc
#<8800> @ 0x1d1c05d0
#NULL
ff(y)
#SEXP @ 0x1d1c0598
#first element of SEXP actual data @ 0x1d1c05c8
#<1500> @ 0x1d1c05c8
#<2400> @ 0x1d1c05cc
#<8800> @ 0x1d1c05d0
#NULL
Последовательная разница в памяти между элементами данных нашего объекта равняется размеру int
типа:
diff(c(strtoi("0x1d1c05c8", 16),
strtoi("0x1d1c05cc", 16),
strtoi("0x1d1c05d0", 16)))
#[1] 4 4
Использование функции [
:
ff(x[1])
#SEXP @ 0x22998358
#first element of SEXP actual data @ 0x22998388
#<1500> @ 0x22998388
#NULL
ff(x[1])
#SEXP @ 0x22998438
#first element of SEXP actual data @ 0x22998468
#<1500> @ 0x22998468
#NULL
Это может быть больше, чем необходимо, расширенный ответ и упрощен c на фактические технические, но, мы надеемся, предлагает earer "большая" картинка.