This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Mystery: Mshr EXC_BAD_ACCESS

0 votes

Dear all,

I am struggling with a bug in my code that buffles me. Let me explain the background.

I have a mesh generator class that works on the main branch. But the main branch is completely unorthodox, with no OO at all. Then I've started refactoring since the analyses are producing good results. Now I have a base class and a derived one. The base class contains all the variables shared by the derived classes, for now only one, and the derived class will use them.

The analysis is handled now with a shared pointer, just to let you know, but the error persists if I revert to simple pointers, or references.

When I generate a mesh, the mshr::generate() generator goes EXC_BAD_ACCESS. I fail to see how this can be.

These are the sources. Remember: master works, inherited doesn't.

As you will see, the code is virtually the same, moreover, I've copied the code from the mesher handler in order to avoid it, but the error remains.

I'm buffled... there's something that I cannot see with my own eyes, maybe I'm tired...

Thanks for any pointers!

ON THE MASTER

// MAIN FILE
Mesh mesh;

// Generate mesh
mesh = handler.generatePolygon(pts, std::max(c.width, c.height) * 0.005);

// CLASS DEFINITION
class MeshHandler
{
public:

    // Rectangle
    Mesh generatePolygon(const std::vector<Point> &pts, double cellSize)
    {
        // Polyline
        mshr::Polygon polyline(pts);

        // Create a simple mesh
        Mesh simple;

        // Generator
        mshr::CSGCGALMeshGenerator2D generator;

        // Set patameters: mesh resolution is NEGATIVE so it will use the cell size
        generator.parameters["mesh_resolution"] = -1.0;
        generator.parameters["cell_size"] = cellSize;

        // Mesh it!
        generator.generate(polyline, simple);

        return simple;
    }

ON THE INHERITED BRANCH

// MAIN FILE
std::shared_ptr<linearAnalysis> analysis = std::make_shared<singleLoad>(planeStress);

// BASE
class linearAnalysis
{
public:

    linearAnalysis(bool planeStress) : planeStress_(planeStress), mesh_(Mesh())
    {
        logger << "+++ virtual base class" << nl;
    }
    // ...

    //! Returns a vector function for the displacement
   virtual std::shared_ptr<Function> linearElastic(double lambda) = 0;

   // Shared variables: all public, we're alone here, no problem

   bool planeStress_;

   MeshHandler gen_;

   Mesh mesh_;

   std::vector<Point> pts_;

   GeometryConstants consts_;        
};

// DERIVED
class singleLoad : public linearAnalysis
{

public:

    singleLoad(bool planeStress) : linearAnalysis(planeStress)
    {
        // Geometry constants
        consts_ = GeometryConstants(false);

        // Points
        pts_.push_back(Point(          0.0,            0.0));      // bottom left
        pts_.push_back(Point(consts_.width,            0.0));      // bottom right
        pts_.push_back(Point(consts_.width, consts_.height));      // top right
        pts_.push_back(Point(          0.0, consts_.height));      // top left

        // Cell size
        double size = std::max(consts_.width, consts_.height) * 0.005;

#if 0
        // Generate mesh
        mesh_ = gen_.generatePolygon(pts_, size); // <---- BOOOOM!            
#else
        // Polyline
        mshr::Polygon polyline(pts_);

        // Generator
        mshr::CSGCGALMeshGenerator2D generator;

        // Set patameters: mesh resolution is NEGATIVE so it will use the cell size
        generator.parameters["mesh_resolution"] = -1.0;
        generator.parameters["cell_size"] = size;

        Mesh simple; // I've tried avoiding using mesh_ from the base class, but... BOOM again.

        // Mesh it!
        generator.generate(polyline, simple); // <---- BOOOOM!
#endif
    }
closed with the note: Reason found: was in another class with undefined behavior.
asked Nov 26, 2015 by senseiwa FEniCS User (2,620 points)
closed Nov 27, 2015 by senseiwa

Even avoiding using pts_ from the base class makes the code read somewhere it shouldn't...

    // **LOCAL** copy of points
    std::vector<Point> q(pts_);

    // Polyline
    mshr::Polygon polyline(q);

    // Generator
    mshr::CSGCGALMeshGenerator2D generator;

    // Set patameters: mesh resolution is NEGATIVE so it will use the cell size
    generator.parameters["mesh_resolution"] = -1.0;
    generator.parameters["cell_size"] = size;

    Mesh simple;

    // Mesh it!
    generator.generate(polyline, simple); // **BOOM!**

A member wasn't initialized correctly. Some width was uninitialized, but for some unlucky reason it worked on the main branch.

When refactoring, this undefined behavior showed up.

I need some vacation...

...