From simon.urbanek at r-project.org  Sun Mar 18 04:47:24 2012
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Sat, 17 Mar 2012 23:47:24 -0400
Subject: [Rd] malloc/calloc/strdup and R's aequivalents
In-Reply-To: <20120318023052.GB13699@siouxsie>
References: <20120318023052.GB13699@siouxsie>
Message-ID: <D83F333D-7CC3-4973-BD0B-F7F08E82F4E4@r-project.org>


On Mar 17, 2012, at 10:30 PM, oliver wrote:

> Hello,
> 
> when looking at "Writing R Extensions"
> with mem-allocation in mind, I wondered,
> which functions to use to substitute
> malloc(), calloc(), realloc() and strdup() and free().
> 
> It looked like Calloc() or R_Calloc() might be useful for
> some of my tasks, but when trying to use R_Calloc() for example,
> I got some error messages which I don't see where they are coming from.
> 
> Maybe I just have forgotten to includ ethe right header file?
> 

Very likely.

#include <R.h>

... you'll need that in any case, obviously.


> So, how to use Calloc() / R_Calloc()?
> What is the prototype of this function/macro?
> 

See R-ext 6.1.2 (or the headers - whichever you prefer).


> And: what if I just want to easily substitute strdup()/free()?
> 

You can always define Strdup() since strdup() is just a shorthand for malloc()+strcpy() -- in fact in R it's easier since Calloc will never return NULL so trivially
#define Strdup(X) strcpy(Calloc(strlen(X)+1, char), X)

But when using Calloc be aware that you have to clean up -- even if there is an error (which is why it is generally not a good idea to use Calloc for anything but memory you want to keep beyond your call).

There are two reasons for removing malloc/calloc: a) R uses custom allocators on systems with poor OS allocators (like Windows) so R's allocation is more efficient [and combining different allocators even worsens the performance] and b) you should think twice about the life span of your objects under error conditions. It is quite challenging to keep that straight, so in most cases it is better to use managed memory instead (but there is a performance trade-off). There are still valid reasons for not using R's allocators, but those are special cases that the author must be conscious about (after weighing the options).


> mkChar seems not to be the right thing, because, what I found in the
> above mentioned documentation, says,m that a C-string is fed in, but
> CHARSXP is what I get as result.
> 
> What I try to do, is, to pick some code and port it to R.
> If I need to rewrite a lot of stuff, just because I need
> to adapt to R, this would be more effort than if it would be possible
> just to have some functions, that could make porting easier.
> 
> For example, if I want to resuse a function, that opens a file
> and needs a   char* stringname
> then it would add more effort if I need to go via CHARSXP or so.
> 

I'm not sure where you are going with this, since all strings will already come as CHARSXPs from R so typically you don't need to allocate anything. The only reason to allocate is to create persistent objects (for which you'd use Calloc) - your example doesn't fit here...


> I would need to rewrite many pieces of the code.
> 
> (Should I implement my own kind of R_str_alloc() ?)
> 
> 
> My main problem at the moemnt is, that I can use R_alloc()
> but when I try to use Calloc() or R_Calloc() I can't compile.
> 
> So, what header-files are necessary, and what are the prototypes
> of these functions?
> 

See above.


> If nothing of that stuff works, I would need to use the original
> calloc() / free() functions, which are deprecated in the above
> mentioned manual.
> 
> 
> Ciao,
>   Oliver
> 
> P.S.: Also I wonder... R-alloc() does not need a free()-like call?
>      Is it freed automaticlaly?
>      And at which time?
>      In the docs is mentioned, at the end of the .C/.Call/.External call.
>      Does this mean, this is freed/reclaimed automatically, when returning
>      from the C-world to the R-world?
>      At (after) return of the extension's code?
> 

Yes. It simply uses an R object so it is subject to regular R object rules and thus gets cleaned up on error as well (unlike anything you use Calloc for).

Cheers,
Simon



[Rd] malloc/calloc/strdup and R's aequivalents
Simon Urbanek