Q:

Computing median of std::vector causing segfault

The following function is supposed to compute the median of a std::vector<double>.
double vecMed(vector<double>& vec) {

    vector<double> copyVec = vec;

    sort(copyVec.begin(), copyVec.end());

    if( copyVec.size()%2 == 0)
        return (copyVec[floor(static_cast<double>(copyVec.size())/2.0)] + copyVec[ceil(static_cast<double>(copyVec.size())/2.0)]) / 2.0;
    else
        return copyVec[copyVec.size()/2];
}

I'm getting a segfault on this line, sometimes:
return (copyVec[floor(static_cast<double>(copyVec.size())/2.0)] + copyVec[ceil(static_cast<double>(copyVec.size())/2.0)]) / 2.0;

Can anyone see a problem with this function?
The segfault might be due to memory corruption elsewhere that I'm unaware of, but I want to make sure I'm not making a subtle or careless mistake in the above code before I explore that possibility.

GDB says:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000428ab6 in vecMed (this=0x7fffffffd1b0, vec=...) at ../globals.cpp:834
834         return (copyVec[floor(static_cast<double>(copyVec.size())/2.0)] + copyVec[ceil(static_cast<double>(copyVec.size())/2.0)]) / 2.0;
(gdb) bt
#0  0x0000000000428ab6 in vecMed (this=0x7fffffffd1b0, vec=...) at ../globals.cpp:834

A:

So much errors in the code!
I guess you want:
#include <algorithm>
#include <vector>

double vecMed(std::vector<double> vec) {
    if(vec.empty()) return 0;
    else {
        std::sort(vec.begin(), vec.end());
        if(vec.size() % 2 == 0)
                return (vec[vec.size()/2 - 1] + vec[vec.size()/2]) / 2;
        else
                return vec[vec.size()/2];
    }
}

A:

First off, if the initial vector is empty, what you're doing is not safe.
Secondly, your logic isn't right in the even case. If copyVec.size() % 2 == 0, it's even, so static_cast<double>(copyVec.size())/2.0 is an integer. So both the floor and ceil are the same thing, so that's probably not what you want to do. Prefer something like:
const int mid = copyVec.size() / 2;
if (copyVec.size() % 2 == 0) {
    return 0.5 * (copyVec[mid] + copyVec[mid+1]); // safe unless size == 0
}
else {
    return copyVec[mid]; // e.g. if size == 3, return copyVec[1]
}

