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

Oleg Sklyar osklyar at ebi.ac.uk
Tue Feb 13 09:55:11 CET 2007


Hello,

is there any one who uses C++ STL classes when programming shared libs 
for R and has had any problems with STL?

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;
}




-- 
Dr Oleg Sklyar * EBI/EMBL, Cambridge CB10 1SD, England * +44-1223-494466



More information about the R-help mailing list