0

C++ rookie here.

I have the following code:

std::vector<float> MyBuffer::readAverage(int numberOfBuffers) {
 std::vector<float> result = std::vector<float>(streams.size());
 for (int i = 0; i < streams.size(); ++i) {
    result[i] = getAverage(streams[i], numberOfBuffers);
 }
 return result;
}

float MyBuffer::getAverage(std::deque<float> input, int numberOfBuffers) {
 float sum = 0;
 for (int i = 0; i < numberOfBuffers; ++i) {
     sum += input[i];
 }
 return sum / numberOfBuffers;
}

This code randomly crashes at getAverage(), I am not sure why.

Strange thing (for me as a C++ rookie at least) is that when I inline the function, it does not crash:

std::vector<float> MyBuffer::readAverage(int numberOfBuffers) {
 std::vector<float> result = std::vector<float>(streams.size());
 for (int i = 0; i < streams.size(); ++i) {
    float sum = 0;
    for (int i1 = 0; i1 < numberOfBuffers; ++i1) {
        sum += streams[i][i1];
    }
    result[i] = sum / numberOfBuffers;
 }
 return result;
}

I can understand that there may be many reasons why this specific code is crashing - so my question relates more to what changes when I inline it, rather than calling a function? In my mind it should be exactly the same thing, but I guess there is something about the way C++ works that I am not grasping?

18
  • 3
    What does the crash message say? Commented Aug 30, 2019 at 17:12
  • 2
    Probably division by zero (check numberOfBuffers) or out of bounds access for input. You can replace sum += input[i]; with sum += input.at(i); to enforce bounds checking. Commented Aug 30, 2019 at 17:13
  • 2
    getAverage makes a copy of std::deque<float> and that could run out of memory. Commented Aug 30, 2019 at 17:15
  • 2
    In my mind it should be exactly the same thing. No, by passing it into a function by value you are creating a copy. Try passing it as const deque<float>& input instead. Commented Aug 30, 2019 at 17:15
  • 1
    std::vector<float> result = std::vector<float>(streams.size()); Why copy-initialisation? Just construct the object normally: std::vector<float> result(streams.size()); Commented Aug 30, 2019 at 17:19

1 Answer 1

1
  1. The program has many potential reasons why it can cause a crash.
    1. bufferDurationMs is not initialized in the provided code, I hope its initialized to value other than 0.
    2. for (int i = 0; i < streams.size(); ++i) { result[i] = getAverage(streams[i], numberOfBuffers); } use result.size() instead of streams.size() as result is lvalue. It is better to check both of these conditions in for.
    3. It is quite possible that numberOfBuffers can be 0 in which case code would crash(divide by zero)
  2. Some optimizations that can be done in the code:

    1. std::vector<float> result = std::vector<float>(streams.size()); use reserve rather than using a costly operation of creating a vector and assigning it to lvalue.
      std::vector result; result.reserve(streams.size());
    2. float MyBuffer::getAverage(std::deque<float> input, int numberOfBuffers) prefer const reference rather than creating a copy of an object

      const std::deque& input

Sign up to request clarification or add additional context in comments.

1 Comment

Seems like the main issue was the fact that I was creating a copy of input. Passing const std::deque<float>& input solved it.

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.