Full_Name: Ian Wilson
Version: 2.6.1
OS: linux
Submission from: (NULL) (128.240.229.7)
The problem is new to R2.6.?. The code works as expected in R-2.5.0. I get the
problem with two different operating systems - an older redhat and new ubuntu
and with both g++4.1 and g++3.4.
I have a problem with character data that is passed back from C++ code. A small
example is the following C++ code and R functions.
#include <sstream>
extern "C" {
void extracttxt( char **txt, int *nchars) {
std::ostringstream oss;
oss << "abcdefghij";
const char *ltxt=oss.str().c_str();
for (int j=0;j<*nchars;j++) *txt[j]=static_cast<char>(ltxt[j]);
}
}
# begin R code
dyn.load("test.so")
"testtxt" <- function() {
nchars <- 80
txt <- .C("extracttxt"
,character(nchars)
,as.integer(nchars))[[1]]
txt
}
a=testtxt()
a[1:10]
# typically the results are something like
[1] "a" "b\033\xba\bfaul\030"
"cz#\b"
[4] "d" "e"
"f"
[7] "g" "h"
"i"
[10] "j"
or
[1] "az#\b" "b" "c"
"d"
[5] "e" "f" "g"
"h"
[9] "i" "j1\xba\brese\030"
This is a bug, but not in R, it's in your program: On Dec 3, 2007, at 9:45 AM, I.J.Wilson at ncl.ac.uk wrote:> Full_Name: Ian Wilson > Version: 2.6.1 > OS: linux > Submission from: (NULL) (128.240.229.7) > > > The problem is new to R2.6.?. The code works as expected in R-2.5.0.it still does in 2.6.x - but it depends on what you expect. You fail to terminate the strings, so you get trailing garbage - it just may have happened that by chance the trailing memory was zero in 2.5.> I get the > problem with two different operating systems - an older redhat and > new ubuntu > and with both g++4.1 and g++3.4. > > I have a problem with character data that is passed back from C++ > code. A small > example is the following C++ code and R functions. > > #include <sstream> > extern "C" { > void extracttxt( char **txt, int *nchars) { > std::ostringstream oss; > oss << "abcdefghij"; > const char *ltxt=oss.str().c_str(); > for (int j=0;j<*nchars;j++) *txt[j]=static_cast<char>(ltxt[j]);As said above, you fail to terminate the string, you want to add something like: txt[j][1]=0; here. Cheers, Simon> > } > } > > # begin R code > dyn.load("test.so") > > "testtxt" <- function() { > nchars <- 80 > txt <- .C("extracttxt" > ,character(nchars) > ,as.integer(nchars))[[1]] > > txt > } > a=testtxt() > a[1:10] > > # typically the results are something like > [1] "a" "b\033\xba\bfaul\030" "cz#\b" > [4] "d" "e" "f" > [7] "g" "h" "i" > [10] "j" > > or > [1] "az#\b" "b" "c" "d" > > [5] "e" "f" "g" "h" > > [9] "i" "j1\xba\brese\030" > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > >
On Mon, 3 Dec 2007, Simon Urbanek wrote:> This is a bug, but not in R, it's in your program: > > On Dec 3, 2007, at 9:45 AM, I.J.Wilson at ncl.ac.uk wrote: > >> Full_Name: Ian Wilson >> Version: 2.6.1 >> OS: linux >> Submission from: (NULL) (128.240.229.7) >> >> >> The problem is new to R2.6.?. The code works as expected in R-2.5.0. > > it still does in 2.6.x - but it depends on what you expect. You fail > to terminate the strings, so you get trailing garbage - it just may > have happened that by chance the trailing memory was zero in 2.5.And there is another bug. What is passed in is 80 zero-length strings, so in principle you cannot extend those strings (as only one byte is allocated for each). It happens that R_alloc currently allocates 8 bytes (because it rounds up to a multiple of 8) and so the example worked, but you cannot rely on such implementation details. The only valid change to an element of a character vector via the .C interface is to replace it by a 'char *' of the same length or shorter. .Call is needed for almost all real applications that alter character vectors.> > >> I get the >> problem with two different operating systems - an older redhat and >> new ubuntu >> and with both g++4.1 and g++3.4. >> >> I have a problem with character data that is passed back from C++ >> code. A small >> example is the following C++ code and R functions. >> >> #include <sstream> >> extern "C" { >> void extracttxt( char **txt, int *nchars) { >> std::ostringstream oss; >> oss << "abcdefghij"; >> const char *ltxt=oss.str().c_str(); >> for (int j=0;j<*nchars;j++) *txt[j]=static_cast<char>(ltxt[j]); > > As said above, you fail to terminate the string, you want to add > something like: > txt[j][1]=0; > here. > > Cheers, > Simon > >> >> } >> } >> >> # begin R code >> dyn.load("test.so") >> >> "testtxt" <- function() { >> nchars <- 80 >> txt <- .C("extracttxt" >> ,character(nchars) >> ,as.integer(nchars))[[1]] >> >> txt >> } >> a=testtxt() >> a[1:10] >> >> # typically the results are something like >> [1] "a" "b\033\xba\bfaul\030" "cz#\b" >> [4] "d" "e" "f" >> [7] "g" "h" "i" >> [10] "j" >> >> or >> [1] "az#\b" "b" "c" "d" >> >> [5] "e" "f" "g" "h" >> >> [9] "i" "j1\xba\brese\030" >> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595