Skip to content

[Rcpp-devel] Possible inconsistency in Rcpp vs stl in erase(iterator, iterator)

6 messages · Toni Giorgino, Dirk Eddelbuettel, Romain Francois

#
Dears,

I am a newbie to Rcpp.  I may have found an off-by-one inconsistency in the
handling of  List::erase(iter1,iter2) operation with respect to its
homologous in the STL (which I suppose is intended to mimic).  In STL,
iter2 can be the container's .end(); in Rcpp, the same gives an out of
boundary error. (See below)

Thanks for the incredible package. Best

Test case...

#include <Rcpp.h>
#include <iostream>

// [[Rcpp::export]]
SEXP truncateTest() {
BEGIN_RCPP

  using namespace std;
  Rcpp::List l;
  std::vector<int> v;

  for (int i=1; i<=10; i++) {
    v.push_back(i);
    l.push_back(i);
  }

  v.erase(v.begin()+5,v.end()-1);
  l.erase(l.begin()+5,l.end()-1); // ?

  cout << "std::vector left with " << v.size() << endl;
  cout << "Rcpp::List  left with " << l.size() << endl;

END_RCPP
}

/*** R
#  library(Rcpp)
#  sourceCpp("truncateTest.cpp")
#  truncateTest()
#  #prints 6 and 5
*/
#
Hi Toni,


Nice example -- we'll take a look.  Probably a buglet at our end.  The STL
are just for convenience: each operation requires _a full copy_ underneath
(as we work on R memory) so they are hogs, which is why nobody may have found
this bug yet.

Two minor comments:  The BEGIN and END macros get autoinserted, you probably
want a return value, and the R code at the bottom get run when you call it:

R> sourceCpp("/tmp/toni.cpp")

R> truncateTest()
std::vector left with 6
Rcpp::List  left with 5
NULL

R> ##prints 6 and 5
R> 


With that, a minor improvement to your code:

#include <Rcpp.h>
#include <iostream>

// [[Rcpp::export]]
SEXP truncateTest() {

  using namespace std;
  Rcpp::List l;
  std::vector<int> v;

  for (int i=1; i<=10; i++) {
    v.push_back(i);
    l.push_back(i);
  }

  v.erase(v.begin()+5,v.end()-1);
  l.erase(l.begin()+5,l.end()-1); // ?

  cout << "std::vector left with " << v.size() << endl;
  cout << "Rcpp::List  left with " << l.size() << endl;

  return R_NilValue;
}

/*** R
truncateTest()
##prints 6 and 5
*/



We'll check end().

Dirk
#
Thanks. I'll have a look.

Le 05/06/13 14:09, Toni Giorgino a ?crit :

  
    
#
This is now fixed in rev 4330.

I'm looking at the other issue you reported.

Le 05/06/13 14:50, Romain Francois a ?crit :

  
    
#
On 5 June 2013 at 16:32, Romain Francois wrote:
| This is now fixed in rev 4330.

Make it rev 4332 which now does the right thing:

R> sourceCpp("/tmp/toni.cpp")

R> truncateTest()
  STL Rcpp
1   1    1
2   2    2
3   3    3
4   4    4
5   5    5
R> 

Dirk

PS Once-more modified 'tony.cpp' below

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::DataFrame truncateTest() {

  Rcpp::NumericVector l;
  std::vector<int> v;

  for (int i=1; i<=10; i++) {
    v.push_back(i);
    l.push_back(i);
  }

  v.erase(v.begin()+5,v.end());
  l.erase(l.begin()+5,l.end());

  return(Rcpp::DataFrame::create(Rcpp::Named("STL")=v, 
				 Rcpp::Named("Rcpp")=l));
}

/*** R
truncateTest()
*/