0

When I try to run this program there is a segmentation fault that is caused in this section:

      std::vector<double> dist1(dist);

      dist1.erase(std::remove(dist1.begin(), dist1.end(), 0), dist1.end());

      max = *std::max_element(dist1.begin(),dist1.end());

      min = *std::min_element(dist1.begin(),dist1.end());

It is the use of the max_element() and min_element() that cause the segmentation fault but I do not see why. What I doing here is copying a vector "dist" to "dist1", removing all occurrences of "0" in the new vector and then searching for the minimum and maximum values from the remaining items in "dist" "max" and "min" are double type variables previously declared. "dist" is previously declared as

 std::vector<double> dist; //vector used to hold the distances between adjacent vertices

 dist.resize(size);

The code compiles otherwise with g++ on a Linux server. Please advice.

1
  • 4
    If every code that compiled successfully was automatically bug free, I'd be out of a job. Commented Dec 22, 2016 at 18:43

3 Answers 3

5

It is the use of the max_element() and min_element() that cause the segmentation fault but I do not see why.

No, it is the dereferencing of the result which causes the segmentation fault.

If you use those functions with an empty range, then the end iterator is returned. Any attempt to dereference that iterator is undefined behaviour. A segmentation fault is one typical but not necessary result of undefined behaviour.

You must either prevent your vector from being empty (and ideally add an assertion for that) or change your program logic to support an empty vector.

Option 1:

// code that prevents dist1 from being empty goes here
// ...
auto const max_iter = std::max_element(dist1.begin(), dist1.end());
assert(max_iter != dist1.end());
auto const max = *max_iter;

Option 2:

auto const max_iter = std::max_element(dist1.begin(), dist1.end());
if (max_iter == dist1.end())
{
    // do something to handle the special situation
}
else
{
    auto const max = *max_iter;
    // normal program flow
}
Sign up to request clarification or add additional context in comments.

Comments

1

Most probably dist1 is empty after applying remove/erase operations.

In case of empty input interval std::min_element and std::max_element return the end of the input range. As a consequence you try to dereference dist1.end() and crash happens.

Comments

-1

I found a way to get it to work. Instead of just using the copy constructor

std::vector<double> dist1(dist)

I also declared and resized my new vector as follows:

std::vector<double> dist1(size);
dist1=dist;

One thing that still bothers me: Shouldn't the copy constructor done all of this?

1 Comment

Undefined behavior is undefined. This did not fix it, just coincidentally/randomly masked the bug.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.