I am trying to write a C function to create a vector of integers that can be used by the R calling function. I do not know the size of the vector in the R calling function. (Well, actually, I have an upper limit on the size, but that is so large that R cannot allocate it. What I'm doing in the function is to do a sieving procedure, and the result will be small enough to fit into my machine's memory.) My reading of sections 6.1.1 and 6.1.2 of the guide on writing R extensions has left me a bit confused. Under R_alloc, I read "R will reclaim the memory at the end of the call" which seems to suggest the storage won't be made available afterwards, so that's not what I should use. As for the alterntaive, under Calloc, I read "This memory lasts until freed by the user", and it's clear that this is to be done within the C function in question. Summary question: how can I allocate memory withing a C function, making it available to an R function that calls the C function? Thanks. Dan. -- View this message in context: http://www.nabble.com/S_alloc-or-Calloc-for-return-value-tp24579062p24579062.html Sent from the R help mailing list archive at Nabble.com.
On Jul 20, 2009, at 7:06 PM, Dan Kelley wrote:> > I am trying to write a C function to create a vector of integers > that can be > used by the R calling function. I do not know the size of the > vector in the > R calling function. (Well, actually, I have an upper limit on the > size, but > that is so large that R cannot allocate it. What I'm doing in the > function > is to do a sieving procedure, and the result will be small enough to > fit > into my machine's memory.) > > My reading of sections 6.1.1 and 6.1.2 of the guide on writing R > extensions > has left me a bit confused. Under R_alloc, I read "R will reclaim > the > memory at the end of the call" which seems to suggest the storage > won't be > made available afterwards, so that's not what I should use. As for > the > alterntaive, under Calloc, I read "This memory lasts until freed by > the > user", and it's clear that this is to be done within the C function in > question. > > Summary question: how can I allocate memory withing a C function, > making it > available to an R function that calls the C function? > > Thanks. Dan. > --You might look at the package bigmemory to see how they attacked the problem. In fact if my reading of their documentation is correct they may have already done your work for you: http://www.stat.yale.edu/~jay/bigmemory David Winsemius, MD Heritage Laboratories West Hartford, CT
On 20 July 2009 at 16:06, Dan Kelley wrote: | I am trying to write a C function to create a vector of integers that can be | used by the R calling function. I do not know the size of the vector in the | R calling function. (Well, actually, I have an upper limit on the size, but | that is so large that R cannot allocate it. What I'm doing in the function | is to do a sieving procedure, and the result will be small enough to fit | into my machine's memory.) | | My reading of sections 6.1.1 and 6.1.2 of the guide on writing R extensions | has left me a bit confused. Under R_alloc, I read "R will reclaim the | memory at the end of the call" which seems to suggest the storage won't be | made available afterwards, so that's not what I should use. As for the | alterntaive, under Calloc, I read "This memory lasts until freed by the | user", and it's clear that this is to be done within the C function in | question. | | Summary question: how can I allocate memory withing a C function, making it | available to an R function that calls the C function? You want R_alloc(). Here, "end of the call" is the call of the R function that calls your C function. This is what you want---the data will be available for the caller of your C code. FWIW R_alloc() is also the only allocation function used in Rcpp (which provides an interface between R and C++). Hth, Dirk -- Three out of two people have difficulties with fractions.
Self-posting the solution, to help those who come across this thread with a similar interest -- My solution, arrived at with the generous help of those who have replied to my question, was to use .Call, as exemplified below. My task was to find indices in a "raw" buffer (input) that match a particular two-byte sequence (b1 and b2). (It's a task that is common in my research area. The files are large, so the use of C was important both to achive speed and to fit within memory constraings.) <R code> indices <- .Call("match2bytes", as.raw(input), as.raw(b1), as.raw(b2)) </R code> <C code> #include <R.h> #include <Rdefines.h> #include <Rinternals.h> /* test R code: buf <- as.raw(c(0xa5, 0x11, 0xaa, 0xa5, 0x11, 0x00)) dyn.load("bitwise.so") m <- .Call("match2bytes", buf, as.raw(0xa5), as.raw(0x11)) print(m) */ SEXP match2bytes(SEXP buf, SEXP m1, SEXP m2) { int i, j, n, n_match; double *resp; unsigned char *bufp, *m1p, *m2p; SEXP res; PROTECT(buf = AS_RAW(buf)); PROTECT(m1 = AS_RAW(m1)); PROTECT(m2 = AS_RAW(m2)); bufp = RAW_POINTER(buf); m1p = RAW_POINTER(m1); m2p = RAW_POINTER(m2); n = LENGTH(buf); n_match = 0; for (i = 0; i < n - 1; i++) { if (bufp[i] == *m1p && bufp[i + 1] == *m2p) { n_match++; ++i; /* skip */ } } PROTECT(res = NEW_NUMERIC(n_match)); resp = NUMERIC_POINTER(res); j = 0; for (i = 0; i < n - 1; i++) { if (j <= n_match && bufp[i] == *m1p && bufp[i + 1] == *m2p) { resp[j++] = i + 1; /* the 1 is to offset from C to R */ } } UNPROTECT(4); return(res); } </C code> -- View this message in context: http://www.nabble.com/S_alloc-or-Calloc-for-return-value-tp24579062p24595838.html Sent from the R help mailing list archive at Nabble.com.