Caco
Caco

Reputation: 1654

R Using function Realoc with .C interface

I am testing a call to a C function from R, using .C interface. The test consists in passing a numeric vector to the C function with no entries, dynamically allocates n positions, makes attributions and return the vector to R.

I'm using Calloc from R.h. The prototype of the function is

type* Calloc(size_t n, type)

as noted in Writing R Extensions.

The problem is that I don't get the new vector with the allocated positions in R. The vector continues to have no entries.

The code in R

fooR <- function(x) {
  if (!is.numeric(x))
    stop("argument x must be numeric")
  out <- .C("foo",
            x=as.double(x))
  return(out$x)
}

x <- numeric()

result <- fooR(x)

The function in C

#include <R.h>

void foo(double *x)
{
  int i, n;

  n = 4;
  x = Calloc(n, double);

  for (i = 0; i < n; i++) {
    x[i] = i;
    printf("%f\n", x[i]); //just to check
  }
}

The question is: Can .C inteface handle with such memory allocation?

Upvotes: 1

Views: 137

Answers (2)

Dirk is no longer here
Dirk is no longer here

Reputation: 368399

Yes, you can use memory management that way but only if you use the .Call() interface instead of the .C() interface.

See the "Writing R Extensions" manual for Memory Allocation as well as Interface Functions.

There are other books, and a number of examples. I prefer C++ over C, and with Rcpp we can hide all the mechanics:

 R> cppFunction('IntegerVector makeVec(int n) { return IntegerVector(n); }')
 R> makeVec(2)
 [1] 0 0
 R> makeVec(4)
 [1] 0 0 0 0
 R> 

This uses both .Call() and R's memory allocation under the hood and is a quick little proof that "yes, you can" in fact create a vector dynamically.

Upvotes: 1

rzymek
rzymek

Reputation: 876

I don't know R language but I know C.

When you are taking a pointer to x as an argument in function foo then you can change content of x inside foo but not x itself.

If you want to change an address of x then you have to take "pointer to pointer to x" i.e. **x.

In your implementation of foo the compiler actually copy the value of *x i.e. memory address to x (compiler passes that address by value). So if you change the address inside the function then it remains unchanged at the outside.

Sorry, if I don't explain this clearly.

Anyway, in pure C the code should look like this:

void foo(double **x)
{
  int i, n;

  n = 4;
  *x = (double*) calloc(n, sizeof(double));

  for (i = 0; i < n; i++) {
    (*x)[i] = i;
    printf("%f\n", (*x)[i]); //just to check
  }
}

And here is the working snippet: https://ideone.com/mRsdUH

Upvotes: 0

Related Questions