Rf_lengthgets
в Rinternals.h
; реализовано в builtin.c:lengthgets
. Возвращаемый указатель должен быть ЗАЩИЩЕН, поэтому один шаблон
SEXP myList;
PROTECT_INDEX ipx;
PROTECT_WITH_INDEX(myList = allocVector( VECSXP, 1 ), &ipx);
REPROTECT(mylist = Rf_lengthgets(mylist, 100), ipx);
Если бы кто-то увеличивал список на основе некоторого неизвестного условия остановки, подход мог бы быть таким же, как в R, с предварительным выделением и заполнением с последующим расширением; следующий псевдо-код:
const int BUF_SIZE = 100;
PROTECT_INDEX ipx;
SEXP myList;
int i, someCondition = 1;
PROTECT_WITH_INDEX(myList=allocVector(VECSXP, BUF_SIZE), &ipx);
for (i = 0; some_condition; ++i) {
if (Rf_length(myList) == i) {
const int len = Rf_length(myList) + BUF_SIZE;
REPROTECT(myList = Rf_lengthgets(mYlist, BUF_SIZE), &ipx);
}
PROTECT(result = some_calculation();
SET_VECTOR_ELT(myList, i, result);
UNPROTECT(1);
// set some_condition
}
Rf_lengthgets(myList, i); // no need to re-PROTECT; we're leaving C
UNPROTECT(1)
return myList;
Это выполняет глубокое копирование myList
, поэтому может стать дорогостоящим и в некоторых отношениях, если у него есть цель оценить some_calculation, то кажется, что проще и не слишком менее эффективно выполнять операции предварительного выделения и расширения в цикле R, вызывая some_calculation и выполняя присваивание внутри цикла.