c++ctriangle

Memory read access violation when using Triangle mesh generation library in C++ project


I'm trying to use J. Shewchuk's mesh generation library Triangle in a C++ program. To do this I first downloaded triangle.h and triangle.c from the Triangle website. Then, in triangle.c I included these defines

#define NO_TIMER
#define TRILIBRARY
#define ANSI_DECLARATORS

I then compiled this into a library file, Triangle.lib, and put this in my C++ project's lib folder (and linked to it). I also copied triangle.h into my project's include folder and modified it to be wrapped with extern "C". With this my project compiles fine and can use the functions from triangle.h.

I then copied the example found in tricall.h into my project as follows:

#define REAL double

struct triangulateio in, mid, out, vorout;

in.numberofpoints = 4;
in.numberofpointattributes = 1;
in.pointlist = (REAL*)malloc(in.numberofpoints * 2 * sizeof(REAL));
in.pointlist[0] = 0.0;
in.pointlist[1] = 0.0;
in.pointlist[2] = 1.0;
in.pointlist[3] = 0.0;
in.pointlist[4] = 1.0;
in.pointlist[5] = 10.0;
in.pointlist[6] = 0.0;
in.pointlist[7] = 10.0;
in.pointattributelist = (REAL*)malloc(in.numberofpoints * in.numberofpointattributes * sizeof(REAL));
in.pointattributelist[0] = 0.0;
in.pointattributelist[1] = 1.0;
in.pointattributelist[2] = 11.0;
in.pointattributelist[3] = 10.0;
in.pointmarkerlist = (int*)malloc(in.numberofpoints * sizeof(int));
in.pointmarkerlist[0] = 0;
in.pointmarkerlist[1] = 2;
in.pointmarkerlist[2] = 0;
in.pointmarkerlist[3] = 0;

in.numberofsegments = 0;
in.numberofholes = 0;
in.numberofregions = 1;
in.regionlist = (REAL*)malloc(in.numberofregions * 4 * sizeof(REAL));
in.regionlist[0] = 0.5;
in.regionlist[1] = 5.0;
in.regionlist[2] = 7.0;
in.regionlist[3] = 0.1;

    /* Make necessary initializations so that Triangle can return a */
    /*   triangulation in `mid' and a voronoi diagram in `vorout'.  */

mid.pointlist = (REAL*)NULL;            /* Not needed if -N switch used. */
mid.pointattributelist = (REAL*)NULL;
mid.pointmarkerlist = (int*)NULL; /* Not needed if -N or -B switch used. */
mid.trianglelist = (int*)NULL;          /* Not needed if -E switch used. */
mid.triangleattributelist = (REAL*)NULL;
mid.neighborlist = (int*)NULL;         /* Needed only if -n switch used. */
mid.segmentlist = (int*)NULL;
mid.segmentmarkerlist = (int*)NULL;
mid.edgelist = (int*)NULL;             /* Needed only if -e switch used. */
mid.edgemarkerlist = (int*)NULL;   /* Needed if -e used and -B not used. */

vorout.pointlist = (REAL*)NULL;        /* Needed only if -v switch used. */
vorout.pointattributelist = (REAL*)NULL;
vorout.edgelist = (int*)NULL;          /* Needed only if -v switch used. */
vorout.normlist = (REAL*)NULL;         /* Needed only if -v switch used. */                                        

triangulate(const_cast<char*>("pczAevn"), &in, &mid, &vorout);

However, I get an error on the last line where I call triangulate. The error is "Exception thrown: write access violation. vertexloop was 0x8E064FF0", and comes from line 14130 in triangle.c

x = vertexloop[0] = pointlist[coordindex++];

Any idea why this error is occurring? Is my approach to including the C code in my C++ program the right way to do so?


Solution

  • Fortunately I've found a C++ version of the code on Github by libigl https://github.com/libigl/triangle. As before, need to include:

    #define NO_TIMER
    #define TRILIBRARY
    #define ANSI_DECLARATORS
    

    In triangle.cpp. Also now including the source files directly in my project instead of compiling to a separate library. With this, no longer get the memory read address error. Looking at the difference between triangle.cpp and triangle.c libigl has added this line:

    /* Define the size large enough to store and operate on a pointer. */
    #define INT_PTR unsigned long long
    

    And everywhere in triangle.c that previously had a pointer to unsigned long has been replaced with INT_PTR. I suspect this has fixed what was initially causing the error.