Alex
Alex

Reputation: 11

sometimes getting a segmentation fault (core dumped)

my program will sometimes run okay but sometimes it crashes in the middle of running with a segmentation fault. and the fault will come at different times each time i run the program. i debugged with gdb and found that the problem is in this function

int chooseLink(int &h, vector<Edge> &link) {
    double r = 1.0*rand() / RAND_MAX;

    if (link[link[h].l_ID].q == link[link[h].r_ID].q) {     // this is where the error occurs
        if (r<0.5)
            return link[h].l_ID;

        return link[h].r_ID;
    }
    else {

        if (r < link[link[h].l_ID].q / (link[link[h].l_ID].q + link[link[h].r_ID].q)) 
            return link[h].l_ID;

        return link[h].r_ID;
    }
}

my program involves calling this function millions of times. can anyone suggest what the problem may be? I'm pretty sure the vector 'link' is not going beyond its capacity. this is my first time posting a problem, so sorry if I haven't provided enough information

update

someone asked why i'm passing h by reference. i thought that passing by reference is better than passing by value because it saves space and the program will run faster. is that not correct?

someone asked for the edge class, so here it is

class Edge {

public:
    int ID;             // ID of edge
    bool type;        // true for constant, false for variable
    double q;                    // quantity on the edge
    int l_ID = 0;           // ID of left edge (equals 0 if doesn't exist)     
    int r_ID = 0;           // ID of right edge

    void assignType(double &p) {
        if (p == 0.5)
            type = false;
        else
            type = true;
    }
};

i added a try-catch block to the function so it looks like this:

int chooseLink(int &h, vector<Edge> &link) {

    try {
         if (h<0 || h>=link.size() ) {
             throw h;
         }
    } catch(...) {
       cout << "ERROR: h = " << h << endl;
    }

    double r = 1.0*rand() / RAND_MAX;

    if (link[link[h].l_ID].q == link[link[h].r_ID].q) {     // this is where the error occurs
        if (r<0.5)
            return link[h].l_ID;

        return link[h].r_ID;
    }
    else {

        if (r < link[link[h].l_ID].q / (link[link[h].l_ID].q + link[link[h].r_ID].q)) 
            return link[h].l_ID;

        return link[h].r_ID;
    }
}

and now i don't get the segmentation fault at all. Also, the program runs fine without ever throwing an exception. what's going on? when i remove this try-catch block, i get the segfault again. i don't understand it

Upvotes: 1

Views: 948

Answers (1)

Thomas Matthews
Thomas Matthews

Reputation: 57718

The first suggestion is always to boundary or range check your parameters:

int chooseLink(int h, vector<Edge> &link)
{
    const unsigned int container_size = link.size();
    // Check index for range.
    if ((h < 0) || (h >= container.size)
    {
       // Report error here.
    }
    else
    {
       // More checking.
       const int left_id = link[h].l_ID;
       const int right_id = link[h].r_ID;
       if ((left_id < 0) || (left_id >= container.size))
       {
          // Perform error handling
       }
       if ((right_id < 0) || (right_id >= container_size))
       {
          // Perform error handling
       }

       // remember to use 'const' for items that won't change.
       const double r = 1.0*rand() / RAND_MAX;

    if (link[left_id].q == link[right_id].q)
    {
        // ALWAYS use braces, even for single statements.
        if (r<0.5)
        {
            return left_id;
        }
        return right_id;
    }
    else
    {

        if (r < link[left_id].q / (link[left_id].q + link[right_id].q))
        {
            return left_id;
        }
        return right_id;
    }
// What does it return here?
}
}  

When in doubt, range check your variables.

Also, check your logic so that all paths of execution return a value.

Upvotes: 1

Related Questions