10

R拡張機能を書く際のガベージコレクションに関するビットを何度も読み直しましたが、これら2つの使用法の違いをまだ理解していません。

SEXP var = PROTECT(allocVector(STRSXP, 100));

SEXP var;
PROTECT(var = allocVector(STRSXP, 100));

これまでのところ、セッションが時々クラッシュするため、最初のものは不運でした (実際のコードとイントロ ガイド自体の両方で、その使用法がよく見られます)。誰かがこれら2つの割り当ての違いを説明できますか?

編集:

いくつかの実験の後、上記の 2 つの間に違いはなく、私が目にするクラッシュ動作の違いは偶然であるという結論に達していると思いますが、より経験豊富な人からの確認をいただければ幸いです。

4

1 に答える 1

7

厳密に同等です。これは PROTECT によって呼び出される関数です ( https://svn.r-project.org/R/trunk/src/main/memory.cから)

SEXP protect(SEXP s)
{
    if (R_PPStackTop >= R_PPStackSize)
    R_signal_protect_error();
    R_PPStack[R_PPStackTop++] = CHK(s);
    return s;
}

static R_INLINE SEXP CHK(SEXP x)
{
    /* **** NULL check because of R_CurrentExpr */
    if (x != NULL && TYPEOF(x) == FREESXP)
    error("unprotected object (%p) encountered (was %s)",
          x, sexptype2char(OLDTYPE(x)));
    return x;
}
#else
#define CHK(x) x
#endif

および from.include/Rinternals.h:

#define TYPEOF(x)   ((x)->sxpinfo.type)

ご覧のとおり、ポインター引数は変更されずに返されるため、

var = PROTECT(p)
PROTECT(var = p)

同等です

于 2013-10-23T12:29:00.033 に答える