[R] anyone has C++ STL classes stability issue if used with R
Oleg Sklyar
osklyar at ebi.ac.uk
Tue Feb 13 10:24:01 CET 2007
Continued: With the following modifications (using pointers) it works
(needs memory cleaning afterwards and new less operator though) and I do
not understand why:
typedef priority_queue<Pixel *> PixelPrQueue;
...
pq.push( new Pixel(i, j, val) );
...
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?
>
> 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