Segmentation fault

I'm having a little trouble with a program I'm working on. I have a vector* in the program but when I try to push an object onto it it gives me a segmentation fault(I'm not quite sure what that is). I even tried to reserve space in the vector but my program still crashed and gave me the same error. It's important to note that in this project I'm required to use pointers for all non-primitive types.

Here's some code see what you think.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class Manager
{
private:
    vector<Account*>* accounts;
    double startValue;
    double taxRate;
    double inflationRate;
    double apr;
    Account* minValBond;
    Account* minValFund;
    Account* maxValFund;
    Account* maxValBond;
    double avgYldBond;
    double avgYldFund;
    double avgBond;
    double avgFund;
    double avgBury;
    Manager(double, double, double, double);
    string* parseString(Account*);
    void printAccount(Account*);
    string* yearlyString(Account*, double);
    void maxMinBond();
    void maxMinFund();
    void calcAvg();
    void printYearlySingle(int, double, double, Account*, Account*, Account*);
    void printYearlyMultiple(int, double, double, Account*, Account*, Account*);

public:
    Manager();
    ~Manager();
    void simulateInvestment(float, int, int);
};


void Manager::simulateInvestment(float startingValue, int yearsIn, int runs) {
    //accounts->reserve(sizeof(Account*)*runs*3);
    for(int n = runs; n > 0; n--) {
        Account* fund = new MutualFund("Mutual Fund", startValue, taxRate, inflationRate);
        Account* bond = new Bond("Bond", startValue, inflationRate, apr);
        Account* burried = new Bury("Burried", startValue, inflationRate);
        accounts->push_back(fund);
        accounts->push_back(bond);
        accounts->push_back(burried);
    }
    double prevValFund = startValue;
    double prevValBond = startValue;
    if(runs == 1)   {
        for(int i = 0; i < yearsIn; i++)    {
            for(unsigned int n = 0; n < accounts->size(); n++)   {
                accounts->at(n)->updateValue(1);
            }
            printYearlySingle(i, prevValFund, prevValBond, accounts->at(0),
                              accounts->at(1), accounts->at(2));
            prevValFund = accounts->at(0)->getValue();
            prevValBond = accounts->at(1)->getValue();
        }
    }
    else if(yearsIn != 0)   {
        //printYearlyMultiple
    }
    return;
}


My program will run fine until line 41 is executed but when i make that function call it terminates.
Last edited on
Where in your Manager class do you instantiate the vector of Account pointers? (Hint: Constructor(s)).
here's the constructors:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Manager::Manager(double valueIn, double taxRateIn,
                 double inflationRateIn, double aprIn)
{
    accounts = new vector<Account*>();
    startValue = valueIn;
    taxRate = taxRateIn;
    inflationRate = inflationRateIn;
    apr = aprIn;
}

Manager::Manager()
{
    Manager(10000, 0.15, 0.03, 0.055);
}
closed account (N85iE3v7)
If possible, please post the Account class constructor as well...
Account is a super class so I just want to point that out. This is sort of an exercise on polymorphism in c++, but here's account.
1
2
3
4
5
6
7
8
9
Account::Account(string ownIn, double valIn, double taxIn, double inflatIn)
{
    owner = new string(ownIn);
    value = valIn;
    tax = taxIn;
    inflation = inflatIn;
    accNum = rand()%9999 + 1;
    accType = DEFAULT_ACC;
}
I don't see why it should fail in 41 if you create the vector in the constructor of Manager. Debug and check all pointers. They should all be valid.
here's my main method too if that helps.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
int main()
{
    srand(time(NULL));
    vector<Account*> accounts;
    double inflation = 0.03;
    double tax = 0.15;
    double ammount = 10000.51;
    int testsRun = 0;
    int testsFailed = 0;
    accounts.push_back(new MutualFund("Mutual Fund", ammount, tax, inflation));
    accounts.push_back(new Bond("Tax Free Bond", ammount, inflation, tax));
    accounts.push_back(new Bury("Burried", ammount, inflation));
    double years = 10.6;
    for(unsigned int i = 0; i < accounts.size(); i++)
    {
        (accounts.at(i))->updateValue(years);
    }
    double expected = ammount * pow((1-inflation), years);
    bool test = (accounts.back())->isValue(expected);
    testsRun++;
    if(!test)
    {
        cout << endl << "Burried Failed" << endl;
        testsFailed++;
        cout << "Value is: " << accounts.back()->getValue()
             << " Expected: " << expected << endl;
    }
    accounts.pop_back();
    expected = ammount * pow((1+ tax - inflation), years);
    test = (accounts.back())->isValue(expected);
    testsRun++;
    if(!test)
    {
        testsFailed++;
        cout<<endl<<"Bond Failed"<<endl;
        cout << "Value is: " << accounts.back()->getValue()
             << " Expected: " << expected << endl;
    }
    accounts.pop_back();
    expected = ammount * pow((1+APR), years);
    test = (accounts.back())->isValue(expected);
    testsRun++;
    if(!test)
    {
        cout << endl << "Fund Failed"<<endl;
        cout << "Value is: " << accounts.back()->getValue()
             << " Expected: " << expected << endl;
        testsFailed++;
    }
    Bond* bondTest = new Bond("Test Bond", 3000.0, 0.02, 0.04);
    bondTest ->updateValue(5.0);
    testsRun++;
    if(!bondTest->isValue(3299.27))
    {
        testsFailed++;
    }
    testsRun++;
    expected = 3000.0 * pow((1+ 0.04 - 0.02), 5.0);
    if(!bondTest->isValue(expected))
    {
        testsFailed++;
        cout << "Value is: " << bondTest->getValue()
             << " Expected: " << expected << endl;
    }
    delete bondTest;
    accounts.pop_back();
    cout << "Tests run:\t\t\t\t" << testsRun;
    cout<<endl<<"Tests Failed:\t\t\t\t" << testsFailed;
    Manager* man = new Manager();
    man->simulateInvestment(1000, 10, 1);
}

Last edited on
@webJose:
How will i know if the pointers are valid?
closed account (N85iE3v7)
Put a breakpoint in the lines you instantiate Account. Inspect these using the debugger tools.
could it possibly have to do with the vector being a pointer itself?
@zlogdan:
the three Account* in simulate investment have a values:
fund = 0x661458
bond = 0x6614d0
burried = 0x662800

They all look fairly legit to me.

Going back to what I was saying in my last post. If you look at line 36 on that code up top you'll see a little commented out piece of code. Well I just want to point out that when that wasn't commented out that line would cause my program to crash. Which makes me think that the problem is really with the vector pointer itself. Does that sound reasonable? Because seemingly every-time I call one of it's methods my program crashes.
Ok now I have something going on that really blows my mind. I just ran my program(not in the debugger), and somehow it executed the print statement on line 52, but if i run in debug it will never get there.

As a side note: This is terribly frustrating.
closed account (N85iE3v7)
@tam0009, if you are using Visual C++ 2003, that is a very buggy IDE/compiler. Anyway, try not allocating vector dynamically as in:

 
vector<Account*>* accounts;


I am forced to job priorities to use that compiler and more than once I solved mysterious issues just upgrading the project to Visual C++ 2008.

Anyway, there is a usual problem with vectors that hold pointers that is when you try to use the vector when the instances that it holds were already deallocated but it does not seem to be the case in your code.
Last edited on
@zlogdan:
I'm not using Visual studio I'm in Code::Blocks w/ the minGW compiler,and about your suggestion:

I hear what your saying and I've debated on doing that (some points are better than none), but one of the many caveats of this project is that I have to use pointers for anything that is not a primitive type, i.e. If I want to use a string I have to use string* str = new string("Blah Blah").

It's kind of silly, but it is what it is. I still may do that though.
@zlogdan:
It runs when I do that though. Jeez!
Topic archived. No new replies allowed.