-1

Here is the chunk of code in question that I've pulled from my program:

#include <vector>

using namespace std; 

vector<double> permittingConstructionCosts(56);
static const int PERMITTING_PERIODS                 = 0;
static const int CONSTRUCTION_PERIODS               = 11;
static const double CONSTRUCTION_COSTS                  = 2169506;
static const double PERMITTING_COSTS                    = 142085;
static const int PERMITTING_CONSTRUCTION_PERIODS = PERMITTING_PERIODS + CONSTRUCTION_PERIODS;

void calcExpenses       // Calculates permitting and construction expenses
   (
    vector<double>&     expense,
    double              value1,
    double              value2
   )
{
int i;

for (i=0; i<=PERMITTING_PERIODS + 1; i++)
{
    expense[i] = value1;
}

for (i=PERMITTING_PERIODS + 2; i<expense.size(); i++)
{
    if (i < PERMITTING_CONSTRUCTION_PERIODS + 2)
    {
        expense[i] = value2;
    }
}
}

int main()
{   
    if (PERMITTING_PERIODS != 0)
        {
            calcExpenses(permittingConstructionCosts, -PERMITTING_COSTS/PERMITTING_PERIODS,     -CONSTRUCTION_COSTS/CONSTRUCTION_PERIODS);
        }
        else
        {
            calcExpenses(permittingConstructionCosts,       0,                  -CONSTRUCTION_COSTS/CONSTRUCTION_PERIODS);
        }

    return 0;
}

According to ideone (http://ideone.com/LpzUny) the code has a runtime error that returns "time: 0 memory: 3456 signal:11".

I've tried to look for solutions on SO and found the following links:

How can I avoid a warning about division-by-zero in this template code?

How to eliminate "divide by 0" error in template code

However, I don't know how to use templates because I am new to c++ and I'm not sure I need to use them in this case so I have no clue how to adapt those solutions to my particular problem if it's even possible.

I'm pretty sure that the "-PERMITTING_COSTS/PERMITTING_PERIODS" is causing the problem but I thought that simply checking the divisor would solve the problem. This function seems to work for every other value other than 0 but I need to account for the case where PERMITTING_PERIODS = 0 somehow.

I would very much appreciate any help I can get. Thanks in advance!

Edit: I actually do initialize the vector in my program but I forgot to put that in because the size is decided elsewhere in the program. The chunk of code works once I fix that part by putting in a number but my program still has a runtime error when I set PERMITTING_PERIODS to 0 so I guess I have to go bug hunting elsewhere. Thanks for the help!

Community
  • 1
  • 1
  • 1
    You're trying to index an empty vector. – user2357112 Jul 16 '16 at 00:50
  • 2
    By the way, if you Googled [`signal 11`](https://www.google.com/search?q=signal+11), you'd find that all the results are about accessing memory that isn't yours, not about dividing by zero. – user2357112 Jul 16 '16 at 00:51
  • What does the debugger tell you when you step through that code? And the very first thing you should do when you get an error you don't recognize is Google (or Bing) the *exact error message*. – Ken White Jul 16 '16 at 00:52
  • 1
    [Signal 11](https://en.wikipedia.org/wiki/Segmentation_fault) is a segmentation fault - i.e. accessing memory spot that is not supposed to. Where do you initialize your `permittingConstructionCosts` vector? Right in the first loop in `calcExpenses` you are trying to write to location in `permittingConstructionCosts` vector that doesn't exist. – ilya1725 Jul 16 '16 at 00:52

2 Answers2

1

The problem lies inside the function, which is called by the else statement in the main function:

for (i=0; i<=PERMITTING_PERIODS + 1; i++)
{
    expense[i] = value1;
}

Here, PERMITTING_PERIODS is 0, thus you loop from 0 to 2 (inclusive).

However, expense.size() is 0, since your vector is empty. As a result, you are trying to access an empty vector, which causes a segmentation fault.

With that said, print the value of i inside the loop, you should see that you try to access expense[0], but the vector is empty, so it has no first slot (basically it doesn't have any)!!

So replace that with:

expense.push_back(value1);

which will allocate enough space for your values to be pushed into the vector.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
0

The answer given in the cited links, (i.e. "How to eliminate "divide by 0" error in template code") applies equally well here. The other answers were given in the context of templates, but this is completely irrelevant. The sample principle applies equally well with non-template code, too. The key principle is to compute a division, but if the denominator is zero, you want to compute the value of zero instead of the division.

So we want to compute -PERMITTING_COSTS/PERMITTING_PERIODS, but use the value of 0 instead of the division when PERMITTING_PERIODS is 0. Fine:

int main()
{   
      calcExpenses(permittingConstructionCosts, 
                   (PERMITTING_PERIODS == 0 ? 0: -PERMITTING_COSTS)/
                   (PERMITTING_PERIODS == 0 ? 1: PERMITTING_PERIODS),
                   -CONSTRUCTION_COSTS/CONSTRUCTION_PERIODS);
      return 0;
}
Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148