[Rd] garbage collection, "preserved" variables, and different outcome depending on "--verbose" or not

Laurent Gautier lgautier at gmail.com
Sun Jul 20 15:01:59 CEST 2008


Dear list,

While trying to identify the root of a problem I am having with
garbage collected variables,
I have come across the following oddity: depending on whether --verbose is set
or not, I obtain different results.

I have made a small standalone example to demonstrate it.
The example is very artificial, but I had a hard time reproducing
reliably the problem.

So when I do: (the content of test.R is at the end of this email)

R --no-save < test.R

[The two last lines of the output are:]
> x[1:3]
[1] 0 0 0

while with

R --verbose --no-save < test.R

[The two last lines of the output are:]
> x[1:3]
[1] 3.733188e-317 3.137345e-317 3.137345e-317


The C code is compiled with:
R CMD SHLIB test_lostobject.c


> sessionInfo()
R version 2.7.1 Patched (2008-07-19 r46081)
x86_64-unknown-linux-gnu

locale:
LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8;LC_COLLATE=en_US.UTF-8;LC_MONETARY=C;LC_MESSAGES=en_US.UTF-8;LC_PAPER=en_US.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US.UTF-8;LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base



### -- file test.R

dyn.load("test_lostobject.so")

x = .Call("lostobject", as.integer(5))

x[1:3]


### ---

###--- file lostobject.c

#include <R.h>
#include <Rdefines.h>



SEXP createObject(void)
{
  SEXP x_R;
  int len_x = 1000000;
  PROTECT(x_R = allocVector(REALSXP, len_x));
  Rprintf("Created 'x' at %p\n", x_R);
  Rprintf("  (mode is %i, length is %i)\n", TYPEOF(x_R), LENGTH(x_R));
  Rprintf("  (first element is %d)\n", REAL(x_R)[0]);
  R_PreserveObject(x_R);
  UNPROTECT(1);
  return x_R;
}

void printObject(SEXP sexp)
{
  Rprintf("object at %p\n", sexp);
  Rprintf("  (mode is %i, length is %i, named is %i)\n",
	  TYPEOF(sexp), LENGTH(sexp), NAMED(sexp));
}

SEXP lostobject(SEXP n_R)
{
  /*
   * This function will:
   * 1- create a numerical vector "x" and "preserve it"
   * 2- make call "list(x)"
   * 3- return "x" to R
   */


  SEXP x_R;
  int i;

  int n = INTEGER(n_R)[0];

  /* Create a numerical vector "x_R" */

  for (i=0; i<n; i++) {
    x_R = createObject();
    R_ReleaseObject(x_R);
    printObject(x_R);
    R_gc();
  }

  x_R = createObject();
  printObject(x_R);
  R_gc();
  R_ReleaseObject(x_R);

  Rprintf("Returning 'x' at %p\n", x_R);
  Rprintf("  (first element is %d)\n", REAL(x_R)[0]);
  return x_R;
}



More information about the R-devel mailing list