Skip to content
Prev 33308 / 63424 Next

Resizing a named vector crashes R with gctorture(TRUE) (PR#13837)

Duncan Murdoch wrote:
OK, the system is the following. Here "you" is not you Duncan, but
the developer that is facing a protect-or-not-protect dilemma.

Every time you are tempted to write

   x = allocVector();

think about what will happen the day someone will come and
add the following line right after your line:

   y = allocVector();

Then cross your finger that s/he will remember to fix your code.
Alternatively you have the option to anticipate and make your
code safer in the long run. It's easy and at the same time you
show that you care more about long term maintainability than
saving an insignificant number of CPU cycles.

It's easy to imagine that people will be reluctant to change
things like:

   ans_elt = allocVector();
   SET_VECTOR_ELT(ans, i, ans_elt);

but I still think that the following is as good and not a lot
harder to read:

   PROTECT(ans_elt = allocVector());
   SET_VECTOR_ELT(ans, i, ans_elt);
   UNPROTECT(1);

But maybe you can have a short list of authorized exceptions
to the rule for these very simple cases.

Otherwise, when you see code like

   /* No protection needed as ExtractSubset does not allocate */
   result = allocVector(mode, n);
   PROTECT(result = ExtractSubset(x, result, indx, call));

it's nice to have a comment, but since 'result' gets finally
protected (ExtractSubset returns the same 'result' that was
passed to it), then why not just do:

   PROTECT(result = allocVector(mode, n));
   result = ExtractSubset(x, result, indx, call);

so you don't need to comment anything and the day someone
decides to allocate in ExtractSubset you are still good.

More generally, when a function is changed from being
non-allocating to be allocating, is the person in charge of
this change also supposed to come to every place where the
function is called and add the missing PROTECT/UNPROTECT?
Even worse, if it's a low-level routine that becomes an
allocating function, it could be that dozens or hundreds
of higher level functions now become allocating (being an
allocating function is a property that propagates to the
parents of the function), so the person can end up having to
check hundreds of places! The task might just become impossible.

H.