[R] anyone has C++ STL classes stability issue if used with R

Duncan Murdoch murdoch at stats.uwo.ca
Tue Feb 13 13:14:27 CET 2007


On 2/13/2007 3:55 AM, Oleg Sklyar wrote:
> Hello,
> 
> is there any one who uses C++ STL classes when programming shared libs 
> for R and has had any problems with STL?

I don't, but I'd suggest asking a technical question like this on 
R-devel instead of R-help if you don't get help here.

I can see a few probably innocuous changes I'd suggest in your code 
below, but nothing obvious:  use Rinternals.h instead of Rdefines.h, 
don't use the Rf_ prefix, check the length of inputs before working with 
the values.

Duncan Murdoch

> 
> In the very simple example below I am constantly getting segfaults when 
> trying to populate the queue. The segfault occurs at what looks like a 
> random index in the loop when pushing another element to the queue. 
> Reproduced on 4 machines. Object x is an Image as in EBImage, i.e. a 3D 
> R-array of numerics for the purpose of this code.
> 
> LENGTH(x) can be up to 1e6 and the number of elements potentially to be 
> in the queue is about 20% of those. But I get segfaults often on a third 
> of fours element being added.
> 
> Tried on R2.5.0-devel, R2.4.1-release and all machines were 64bit Linux 
> with kernels 2.6.9 (stable CentOS), 2.6.17 (stable Ubuntu) and 2.6.20 
> (Ubuntu devel).
> 
> Here are the compilation options of this particular module (built as 
> part of EBImage, which generally compiles and works just fine):
> 
> --------------------------------------------------------------------------
> g++ -I/home/osklyar/R/R-2.5.0-40659/include 
> -I/home/osklyar/R/R-2.5.0-40659/include  -I/usr/local/include 
> -DUSE_GTK -DGLIB_GETTEXT -I/usr/include/gtk-2.0 
> -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo 
> -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 
> -I/usr/lib/glib-2.0/include   -Wall -g -O2 -Wall -pthread -I/usr/include 
> -O2 -g -O2 -g  -fpic  -O2 -g  -c filters_watershed.cpp -o 
> filters_watershed.o
> --------------------------------------------------------------------------
> And the linker:
> --------------------------------------------------------------------------
> g++ -shared -L/usr/local/lib64 -o EBImage.so colors.o conversions.o 
> display.o filters_distmap.o filters_magick.o filters_morph.o 
> filters_propagate.o filters_thresh.o filters_watershed.o init.o io.o 
> object_counting.o tools.o -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 
> -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender 
> -lXinerama -lXi -lXrandr -lXcursor -lXfixes -lpango-1.0 -lcairo -lX11 
> -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0   -L/usr/lib 
> -L/usr/X11R6/lib -lfreetype -lz -L/usr/lib -lMagick -llcms -ltiff 
> -lfreetype -ljasper -ljpeg -lpng -lXext -lSM -lICE -lX11 -lbz2 -lxml2 
> -lz -lpthread -lm -lpthread
> --------------------------------------------------------------------------
> 
> It could be I am missing something totally simple and therefore get 
> these errors, but I cannot identify what.
> 
> Thanks for help,
> Oleg
> 
> -----------------------------------------
> // common.h also includes R includes:
> // #include <R.h>
> // #include <Rdefines.h>
> // #include <R_ext/Error.h>
> 
> #include "common.h"
> 
> #include <queue>
> 
> using namespace std;
> 
> struct Pixel {
>      int x, y;
>      double intens;
>      /* the code will also fail with the same segfault if I remove all
>       * the constructors here and use the commented block below instead
>       * of pq.push( Pixel(i, j, val) */
>      Pixel() {x = 0; y = 0; intens = 0; };
>      Pixel(const Pixel& px) { x = px.x; y = px.y; intens = px.intens; };
>      Pixel(int i, int j, double val): x(i), y(j), intens(val) {};
> };
> 
> bool operator < (const Pixel & a, const Pixel & b) {
>      return a.intens < b.intens;
> };
> 
> typedef priority_queue<Pixel> PixelPrQueue;
> 
> SEXP
> lib_filterInvWS (SEXP x) {
>      SEXP res;
>      int i, j, index;
>      double val;
>      PixelPrQueue pq;
> 
>      int nx = INTEGER ( GET_DIM(x) )[0];
>      int ny = INTEGER ( GET_DIM(x) )[1];
>      int nz = INTEGER ( GET_DIM(x) )[2];
>      int nprotect = 0;
> 
>      PROTECT ( res = Rf_duplicate(x) );
>      nprotect++;
> 
>      // Pixel px;
>      for (int im = 0; im < nz; im++ ) {
>          double * src = &( REAL(x)[ im * nx * ny ] );
>          double * tgt = &( REAL(res)[ im * nx * ny ] );
> 
>          for ( j = 0; j < ny; j++ )
>              for ( i = 0; i < nx; i++ ) {
>                  index = i + nx * j;
>                  val = src[ index ];
>                  if ( val > BG ) {
>                      tgt[ index ] = -1;
>                      // px.x = i; px.y = j; px.intens = val; pq.push(px);
>                      pq.push( Pixel(i, j, val) );
>                      continue;
>                  }
>                  tgt[ index ] = BG;
>              }
>      }
> 
>      /* my main code was here, but deleted for debug */
> 
>      UNPROTECT (nprotect);
>      return res;
> }
> 
> 
> 
>



More information about the R-help mailing list