[Rcpp-devel] Rcpp Module problem: R crash

该走了 gaizoule at gmail.com
Mon Jan 21 18:55:18 CET 2013


I am tring to use Rcpp Module to export C++ class to R, but meet some
problem.
Here is my code:
###########################################################################################
/* file PL modules.cpp */
using namespace Rcpp;
using namespace std;

class SymPL {
public:
  SymPL(vector<double>  close);
  void update(int idx,
      double  txnqty,
      double  txnprc);
  DataFrame toDF();


  int nrow;
  vector<double> txn_qty, txn_prc, txn_fee;
  vector<double> pos_qty, close_prc, PL;
};

SymPL::SymPL(vector<double>  close) {
  nrow = close.size();
  txn_qty = vector<double>(nrow);
  txn_prc = vector<double>(nrow);
  txn_fee = vector<double>(nrow);
  pos_qty = vector<double>(nrow);
  close_prc = vector<double>(close);
  PL = vector<double>(nrow);
}

void SymPL::update(int  idx,
   double  txnqty,
   double  txnprc) {
  txn_qty[idx] = txnqty;
  txn_prc[idx] = txnprc;
  txn_fee[idx] = 0;  //calfee(txnqty*txnprc); todo: write a function to cal
fee
  if(idx == 0) { //index start with 0
    pos_qty[idx] = txnqty;
    PL[idx] = txnqty * (close_prc[idx] = txnprc) - txn_fee[idx];
  }
  else {
    pos_qty[idx] = txnqty + pos_qty[idx-1];
    PL[idx] = pos_qty[idx-1] * (close_prc[idx] - close_prc[idx-1]) +
      txnqty * (close_prc[idx] = txnprc) - txn_fee[idx];
  }
}

DataFrame SymPL::toDF() {
  DataFrame PLrecord = DataFrame::create(_["txn.qty"] = txn_qty,
 _["txn.prc"] = txn_prc,
 _["txn.fee"] = txn_fee,
 _["pos.qty"] = pos_qty,
 _["close.prc"] = close_prc,
 _["PL"] = PL);
  return PLrecord;
}

class PortPL {
public:
  CharacterVector symnames;
  int sym_num;
  double initMoney;
  int period_num;
  vector<double> total_eq;
  vector<double> total_PL;
  vector<double> period_return;
  vector<double> cum_return;
  DatetimeVector timeindex;

  PortPL(SEXP times,
 SEXP CLprc, double initM);
  void update(int idx, NumericVector txnqty_vec,
      NumericVector txnprc_vec);
  void exit(int idx, NumericVector txnprc_vec);
  void hold(int idx);
  NumericVector getpos(int idx);
  List getSymPLs();

private:
  vector<SymPL> symbols;

};

PortPL::PortPL(SEXP times,
       SEXP CL,
       double initM):
  timeindex(times) {
  List CLprc(CL);
  sym_num = CLprc.size();
  symnames = CLprc.names();
  initMoney = initM;
  //timeindex = DatetimeVector(times);
  period_num = timeindex.size();

  //initialize total_eq, total_PL, period_return, cum_return
  total_eq = vector<double>(period_num);
  total_PL = vector<double>(period_num);
  period_return = vector<double>(period_num);
  cum_return = vector<double>(period_num);

  //initialize each SymPL
  for(int i = 0; i < sym_num; i++) {
    vector<double> close = as<vector<double> >(CLprc[i]);
    symbols[i] = SymPL(close);
  }
}

void PortPL::update(int idx, NumericVector txnqty_vec,
       NumericVector txnprc_vec) {
  double sumPL = 0;
  for(int i = 0; i < sym_num; i++) {
    symbols[i].update(idx, txnqty_vec[i], txnprc_vec[i]);
    sumPL += symbols[i].PL[idx];
  }

  total_PL[idx] = sumPL;
  if(idx == 0) {// index starts with 0
    total_eq[idx] = initMoney + total_PL[idx];
    period_return[idx] = total_PL[idx] / initMoney;
    cum_return[idx] = total_PL[idx] / initMoney;
  }
  else {
    total_eq[idx] = total_eq[idx-1] + total_PL[idx];
    period_return[idx] = total_PL[idx] / total_eq[idx];
    cum_return[idx] = total_eq[idx] / initMoney - 1;
  }
}

void PortPL::hold(int idx) {
  NumericVector tempv(sym_num, 0.0);
  this->update(idx, tempv, tempv);
}

void PortPL::exit(int idx, NumericVector txnprc_vec) {
  NumericVector curr_pos(sym_num);
  for(int i = 0; i < sym_num; i++) {
    curr_pos[i] = symbols[i].pos_qty[idx-1];
  }
  this->update(idx, curr_pos, txnprc_vec);
}

NumericVector PortPL::getpos(int idx) {
  NumericVector curr_pos(sym_num);
  for(int i = 0; i < sym_num; i++) {
    curr_pos[i] = symbols[i].pos_qty[idx-1];
  }
  return curr_pos;
}

List PortPL::getSymPLs() {
  List allsym(sym_num);
  for(int i = 0; i < sym_num; i++){
    allsym[i] = symbols[i].toDF();
  }
  allsym.names() = symnames;
  return allsym;
}

RCPP_MODULE(PortPL_module) {
  class_<PortPL>("PortPL")
    .constructor<SEXP, SEXP, double>()
    .field("total.eq", &PortPL::total_eq)
    .field("total.PL", &PortPL::total_PL)
    .field("symnames", &PortPL::symnames)
    .field("cum.return", &PortPL::cum_return)
    .field("period.return", &PortPL::period_return)
    .field("initMoney", &PortPL::initMoney)

    .method("update", &PortPL::update)
    .method("exit", &PortPL::exit)
    .method("hold", &PortPL::hold)
    .method("getpos", &PortPL::getpos)
    .method("getSymPLs", &PortPL::getSymPLs)
    ;
}

#######################################################################

## R code
library(inline)
library(Rcpp)

fx <- cxxfunction(signature(),
                  includes = paste(readLines("PnL module.cpp"),
                    collapse =  "\n"),
                  plugin = "Rcpp")

port <- Module("PortPL_module", getDynLib(fx))
PortPL <- port$PortPL

datel <- as.POSIXct(Sys.Date()+1:10)
colse <- 1:10
initM <- 1e5

testport <- new(PortPL, datel, list(hjs=colse), initM)

Then the R crash with error message:

*** caught segfault ***
address (nil), cause 'memory not mapped'

Traceback:
 1: .External(class__newInstance, module, pointer, ...)
 2: new_CppObject_xp(fields$.module, fields$.pointer, ...)
 3: Rcpp:::cpp_object_initializer(.self, .refClassDef, ...)
 4: .Object$initialize(...)
 5: initialize(value, ...)
 6: initialize(value, ...)
 7: new(PortPL, datel, list(hjs = colse), initM)

Possible actions:
1: abort (with core dump, if enabled)
2: normal R exit
3: exit R without saving workspace
4: exit R saving workspace
Selection:

######################################################################
I just can not figure out what is wrong, Is there anyone can help me check
out? Thanks in advance!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130122/c71870be/attachment.html>


More information about the Rcpp-devel mailing list