Поменяйте местами два SEXP без копирования

Возможно, самое простое решение использует одну из моих любимых малоизвестных функций, strcspn() :

buffer[strcspn(buffer, "\n")] = 0;

Если вы хотите, чтобы она также обрабатывала '\r' (скажем, , если поток двоичный):

buffer[strcspn(buffer, "\r\n")] = 0; // works for LF, CR, CRLF, LFCR, ...

Функция подсчитывает количество символов до тех пор, пока оно не достигнет '\r' или '\n' (другими словами, он найдет первый '\r' или '\n'). Если он ничего не ударил, он останавливается на '\0' (возвращает длину строки).

Обратите внимание, что это отлично работает, даже если нет новой строки, поскольку strcspn останавливается на '\0'. В этом случае вся строка просто заменяет '\0' на '\0'.

1
задан MACHERKI M E 3 March 2019 в 15:05
поделиться

1 ответ

Ваш код не поменяет местами x и y.

Обратите внимание, что нам не нужно, чтобы Rcpp менял местами x и y без копирования. Мы можем сделать это в прямой R, как показано ниже. x изначально имеет адрес 0x16d9fa08, а y изначально имеет адрес 0x170291d8 и после свопинга, выполненного в R, их адреса обмениваются, и все под ними остается с адресами, изначально связанными с теми же родительскими адресами, то есть содержимое по первоначальным адресам и не был скопирован.

library(pryr)

x <- data.frame(a = 1:2)
y <- data.frame(y = 3:4)

inspect(x)
## <VECSXP 0x16d9fa08>
##   <INTSXP 0x1459a5b0>
## attributes: 
##   <LISTSXP 0x1203a7c0>
## ...snip...

inspect(y)
## <VECSXP 0x170291d8>
##   <INTSXP 0x12039288>
## attributes: 
##   <LISTSXP 0x14894a10>
## ...snip...

tmp <- x
x <- y
y <- tmp

inspect(x)
## <VECSXP 0x170291d8>
##   <INTSXP 0x12039288>
## attributes: 
##   <LISTSXP 0x14894a10>
## ...snip...

inspect(y)
## <VECSXP 0x16d9fa08>
##   <INTSXP 0x1459a5b0>
## attributes: 
##   <LISTSXP 0x1203a7c0>
## ...snip...
0
ответ дан G. Grothendieck 3 March 2019 в 15:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: