在一个在R包中调用的C函数中,我需要对它进行排序 数字。为了与R做的一致,我想称之为 R使用的排序算法/函数,所以R_orderVector()。我得到了 完全在R_orderVector()调用时出现分段错误。 下面是一个最小的工作示例('最小工作包'的文件) 它再现了分割错误。我做错了什么?
### DESCRIPTION ################################################################
Package: foo
Version: 0.0-1
Encoding: UTF-8
Title: Sorting from C via R's R_orderVector()
Description: See title
Authors@R: c(person(given = "Foo", family = "Bar", role = c("aut", "cre"), email = "foo@bar.com"))
Author: Foo Bar [aut, cre]
Maintainer: Foo Bar <foo@bar.com>
Depends: R (>= 3.0.0)
Imports:
Suggests:
Enhances:
License: GPL-2 | GPL-3
NeedsCompilation: yes
Repository: CRAN
Date/Publication: 2014-03-25 15:26:50
### NAMESPACE ##################################################################
useDynLib(foo, .registration = TRUE)
export("myRsort")
### ./R/mySort.R ###############################################################
myRsort <- function(x) {
stopifnot(is.numeric(x), length(x) <= 64)
myRsort_ <- NULL # to avoid "myRsort_: no visible binding for global variable 'myRsort_'"
.Call("myRsort_", x)
}
### ./man/myRsort.Rd ###########################################################
\name{myRsort}
\alias{myRsort}
\title{Using R's Sorting Algorithm from C}
\description{
R's sorting algorithm is called from C.
}
\usage{
myRsort(x)
}
\arguments{
\item{x}{vector}
}
\value{
vector
}
\author{Marius Hofert}
\examples{
set.seed(271)
x <- runif(10)
myRsort(x)
}
\keyword{utilities}
### ./src/init.c ###############################################################
#include <R.h>
#include <Rinternals.h>
#include <R_ext/Rdynload.h>
#include "myRsort.h"
static const R_CallMethodDef callMethods[] = {
{"myRsort_", (DL_FUNC) &myRsort_, 1},
{NULL, NULL, 0}
};
void R_init_foo(DllInfo *dll)
{
R_useDynamicSymbols(dll, FALSE);
R_registerRoutines(dll, NULL, callMethods, NULL, NULL); /* s. WRE (2015, Section 5.4) */
}
### ./src/myRsort.c ############################################################
#include "myRsort.h"
void myRsort_aux(double *x, int n, double *res)
{
int *ind; /* pointer to vector of indices as required for order (permutation of 0:(n-1)) */
ind = (int *) R_alloc(n, sizeof(int));
SEXP xsexp = PROTECT(allocVector(REALSXP, n)); /* turn x into SEXP */
double *xsexp_ = REAL(xsexp); /* pointer */
R_orderVector(ind, n, xsexp, TRUE, TRUE); /* nalast (use same default as order()); decreasing=TRUE */
/* the last line generates a seg-fault */
int i;
for(i=0; i<n; i++) res[i] = x[ind[i]];
}
SEXP myRsort_(SEXP x)
{
double *x_ = REAL(x); /* pointer to n-vector */
int n = LENGTH(x); /* length n */
int maxlen = 64; /* vector can be at most of length 64 here */
SEXP res = PROTECT(allocVector(REALSXP, maxlen)); /* result */
double *res_ = REAL(res); /* pointer to the (sorted) result */
myRsort_aux(x_, n, res_);
UNPROTECT(1);
return res;
}
### ./src/myRsort.h ############################################################
#ifndef myRsort_H
#define myRsort_H
#include <R.h>
#include <Rinternals.h>
#include <Rmath.h>
void myRsort_aux(double *x, int n, double *res);
SEXP myRsort_(SEXP x);
#endif
答案 0 :(得分:0)
似乎您:
UNPROTECT
。myRsort_aux
中的值。R_orderVector
函数。这是一个可以Rcpp::sourceCpp
编辑的工作示例:
#include <Rcpp.h>
void myRsort_aux(double *x, int n, double *res)
{
int *ind = (int *) R_alloc(n, sizeof(int));
SEXP xsexp = PROTECT(Rf_allocVector(REALSXP, n));
// you forgot to copy the values?
for(int i = 0; i < n; ++i)
REAL(xsexp)[i] = x[i];
// a call as in https://github.com/wch/r-source/blob/7dcdfc2d2d0ce3ce6fe84aa1cf0d27b5cbc833fc/src/main/sort.c#L1096
R_orderVector(ind, n, Rf_lang1(xsexp), TRUE, TRUE);
for(int i = 0; i < n; i++)
res[i] = x[ind[i]];
UNPROTECT(1); // seems like you forgot this
}
// [[Rcpp::export(rng = false)]]
SEXP myRsort_(SEXP x)
{
double *x_ = REAL(x);
int n = LENGTH(x);
int maxlen = 64;
SEXP res = PROTECT(Rf_allocVector(REALSXP, maxlen));
double *res_ = REAL(res);
myRsort_aux(x_, n, res_);
UNPROTECT(1);
return res;
}
/*** R
set.seed(1)
to_be_sorted <- rnorm(10)
head(myRsort_(to_be_sorted), 10)
#R> [1] 1.5952808 0.7383247 0.5757814 0.4874291 0.3295078 0.1836433 -0.3053884 -0.6264538 -0.8204684 -0.8356286
*/
您可能只使用R_rsort
in this case.