Static variables/deque and objects

1.4k views Asked by At

I have a problem with static vars/deque and objects. I am calculating some statistics for a real time data stream - mean, median, skew etc. As this is streaming data I make use of static vars, or in this version static container (deque). I have made several versions and they all exhibit the same problem. Even though I make two instances of the same method, the static deque seems to be shared. I have the following code (not the most efficient but readable):

double Mean(double& lastValue, const int& length)
{
    static std::deque<double> buffer(length);
    double sum = 0.0;

    buffer.pop_back();
    buffer.push_front(lastValue);

    for (int j = 0; j < length; j++) {
        try {
            sum += buffer.at(j);
        }
        catch (const std::out_of_range& oor) {
            std::cerr << "Out of Range error: " << j << " - " << oor.what() << '\n';
        }
    }

    return length != 0 ? sum / length : 0;
}

If I make two instances of this like:

Stats s1, s2;
s1.Mean(streamData, 20);
s2.Mean(streamData, 30);

I get Out Of Range error.

Questions:

  1. What is causing the out_of_range exception?
  2. I might be wrong, but it seems like the static deque is shared between two objects - how is this possible?

Any help appreciated!

1

There are 1 answers

2
chrphb On BEST ANSWER

on 2: a static variable in C has a lifetime that expands over the lifetime of the program. Therefore, there is only one instance of your buffer variable when the program is running.

on 1: so in your program: you first construct a deque buffer of size 20 using the s1 object, then you try to use it for a size of 30 using the s2 object. This causes the out of range error on the 20-29 range as the variable is the one statically created.

Using static variables inside code is generally not a good idea.

Edit:

What you really want is to have a deque member variable in your Stats class.

 class Stats {
 private:
  std::deque<double> buffer;
  ...

you access this variable (per object) in your Mean function. (do not forget to initialise it in the constructor of Stats).

If you need to resize the deque, you can use:

buffer.resize(length);