From ernest.turro at ic.ac.uk  Mon Feb 26 18:32:17 2007
From: ernest.turro at ic.ac.uk (Ernest Turro)
Date: Mon, 26 Feb 2007 17:32:17 +0000
Subject: [Rd] R/C++/memory leaks
In-Reply-To: <B5F49FDC-5EE5-4CC1-8F53-43CBBE915A7F@r-project.org>
References: <39CFDB8F-918C-48FB-9A6D-D8055D828C13@ic.ac.uk>
	<B5F49FDC-5EE5-4CC1-8F53-43CBBE915A7F@r-project.org>
Message-ID: <065FE26B-74E7-4867-A214-4C555DE35762@ic.ac.uk>

Hi Simon,

On 26 Feb 2007, at 16:58, Simon Urbanek wrote:

> Ernest,
>
> On Feb 25, 2007, at 12:37 PM, Ernest Turro wrote:
>
>> I have wrapped a C++ function in an R package. I allocate/ 
>> deallocate memory using C++ 'new' and 'delete'. In order to allow  
>> user interrupts without memory leaks
>
> How do you allow for user interrupts? R doesn't allow interrupts  
> while in .C/.Call on purpose,

void R_CheckUserInterrupt(void)


> so it's up to your code to handle interrupts properly. This also  
> implies that you can use the regular methods for error recovery  
> available in your language and handle the interrupt yourself by  
> freeing the memory as needed, your code shouldn't return to R until  
> it has cleaned everything up ...

How can I detect an interrupt from R inside the C/C++ code without  
using the R API? SIGINTs don't get passed on if they come from within  
R...

>
>
>> I've moved all the delete statements required after an interrupt  
>> to a separate C++ function freeMemory(), which is called using  
>> on.exit() just before the .C() call.
>>
>
> This sounds a bit dangerous - how can the separate function know  
> about the previous call and the state it was in before the  
> interrupt (save for hard-wiring everything into one instance)?  
> Again, the crucial part is the interrupt handling in your code - it  
> may fail to release some objects...
>

I have to declare variables for any allocated memory globally:

static int foo*;

extern "C"
void func(...) {
	foo = new int[1024];

	// heavy computation
	// inside loop:
	R_CheckUserInterrupt()
	//end heavy computation
}

extern "C"
void freemem(...) {
	delete [] foo;
}

in R:

func <- function() {
on.exit(.C("freemem"))
.C("func")
}



Cheers,

Ernest

> @Ross [see follow-up]: R_RegisterCFinalizerEx is called on R exit  
> if desired (see arguments). However, I don't think this is relevant  
> to the discussed issue as a process termination frees all its  
> memory. Moreover I don't think Ernest wants to wrap all his classes  
> to R objects - we're not talking about the GC here, it is supposed  
> to be C++ internal issue.
>
> Cheers,
> Simon
>
>
>> I am concerned about the following. In square brackets you see R's
>> total virtual memory use (VIRT in `top`):
>>
>> 1) Load library and data [178MB] (if I run gc(), then [122MB])
>> 2) Just before .C [223MB]
>> 3) Just before freeing memory [325MB]
>> 4) Just after freeing memory [288MB]
>> 5) After running gc() [230MB]
>>
>> So although the freeMemory function works (frees 37MB), R ends up
>> using 100MB more after the function call than before it. ls() only
>> returns the data object so no new objects have been added to the
>> workspace.
>>
>> Do any of you have any idea what could be eating this memory?
>>
>> Many thanks,
>>
>> Ernest
>>
>> PS: it is not practical to use R_alloc et al because C++ allocation/
>> deallocation involves constructors/destructors and because the C++
>> code is also compiled into a standalone binary (I would rather avoid
>> maintaining two separate versions).
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>



[Rd] R/C++/memory leaks
Ernest Turro