Still need help with Class c++

Crashing after the whole program executes! Please help!

main.cpp
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <iostream>
#include <iomanip>
#include <cstddef>
#include <fstream>
#include"squirrel.h"
#include"tree.h"
#include"hoard.h"
#include"nut.h"
using namespace std;

int main()
{
	int num_of_squirrels;
	int num_of_trees;
	int skip_factor;
	int total_nuts;
	Squirrel squirrel;
	Tree nut;
	
	cout << "Please enter the number of squirrels:  ";
	cin >> num_of_squirrels;
	cout << "Please enter the number of trees:  ";
	cin >> num_of_trees;
	//Creating the correct amount
	Squirrel *squirrels = new Squirrel[num_of_squirrels];
	Hoard *hoards = new Hoard [num_of_squirrels];
	Tree *trees = new Tree[num_of_trees];
	//Getting and setting skip factor
	//assigning hoard owners
	
	for(int i=0;i<num_of_squirrels;++i)
	{
		cout << "Please enter the skip factor for squirrel # "<<(1+i)<<": ";
 		cin >> skip_factor;
 		
 		while (skip_factor > num_of_trees)
		{
 			skip_factor = skip_factor - num_of_trees;
 		}	
 		if (skip_factor == 0)
		{
 			skip_factor = 1;
 		}
 		squirrels[i].set_skip_factor(skip_factor);
 		squirrels[i].set_location(skip_factor);
 		
 	
 		//Sets the owners of the hoards to each squirrel
 		hoards[i].set_owner(squirrels);
	}
	
	int round = 1;
	total_nuts = 0;
	while(total_nuts < 100)
	{
		cout << endl;
		cout << "Round " << round << ":" << endl;
		if(round % 2 != 0)
		{
			for(int i = 0; i < num_of_trees; i++)
			{
				cout << "Tree " << i+1 << " has " << trees[i].get_nuts_left() << endl;
			}
			for(int i = 0; i < num_of_squirrels; i++)
			{
				cout << "Squirrel " << i+1 << " is at Tree " << squirrels[i].get_location()+1 << endl;
			}
			for(int i = 0; i < num_of_squirrels; i++)
			{
				// This is where we should determine if they fight. Idk how to go about that.
				int myvar;
				int myvar7;
				cout << "Squirrel " << i+1 << " collects a nut from Tree " << squirrels[i].get_location()+1 << endl;
				myvar = squirrels[i].get_location();
				trees[myvar].remove_nut();
				squirrels[i].move_location(myvar, skip_factor, num_of_trees);
				// Not sure how to take the nut from the tree because of location issues
				myvar7 = myvar +1;
				squirrels[i].take_nut();
			}
			
		
		}
		if(round % 2 == 0)
		{
			// Not sure if any of this works because we need to figure out what is wrong with location
			for(int i = 0; i < num_of_squirrels; i++)
			{
				if(squirrels[i].has_nut()==true)
				{
					hoards[i].add_nut();
					cout << "Squirrel " << i+1 << " deposited a nut into its hoard." << endl;
				}
				else
				{
					cout << "Squirrel " << i+1 << " had no nut to deposit." << endl;
				}
				
				
			}
			for(int i = 0; i < num_of_squirrels; i++)
			{
				cout << "Squirrel " << i+1 << "'s Hoard contains " << hoards[i].get_number_of_nuts() << " nuts." << endl;
			}	
		}
		
		round++;
		// This will be moved higher up once we figure out how to see if the squirrels are fighting
	    total_nuts++;
	    if (round==100){
		getchar();
	}	
	}

}
	


tree.h
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
#pragma once
#include <iostream>
#include "hoard.h"
#include "nut.h"
#include "squirrel.h"


class Tree;
class Nut;
class Squirrel;
class Hoard;

class Tree{
	
	Nut *nuts;
	
public:
	int remove_nut();
	int get_nuts_left();
	int nuts_left;
	
	~Tree();
	Tree();
};


squirrel.h
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
#pragma once
#include <iostream>
#include "hoard.h"
#include "nut.h"
#include "tree.h"

class Hoard;
class Tree; 
class Squirrel;

class Squirrel
{
	Nut* nut_carried;
	int skip_factor;
	int location;
	
public:
	Squirrel();
	void take_nut(Tree from_tree);
	void store_nut(Hoard hoard);
	bool has_nut();
	void go_to(Tree* tree);
	int get_skip_factor();
	void set_skip_factor(int factor);
	void set_location(int loco);
	int get_location();

};


hoard.h
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
#pragma once
#include <iostream>

#include "tree.h"
#include "nut.h"
#include "squirrel.h"

class Hoard;
class Squirrel;
class Tree;
class Nut;

class Hoard{

	Squirrel* owner;
	Nut *nuts;
	int number_of_nuts;
	
public:
	int add_nut();
	int get_number_of_nuts();
	Hoard();
	~Hoard();
	void set_owner(Squirrel* name);
};


nut.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once
#include <iostream>
#include "hoard.h"
#include "tree.h"
#include "squirrel.h"



class Nut;

class Nut
{
public:
	Nut();
};


squirrel.cpp
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
#include<iostream>
using namespace std;
#include"squirrel.h"
#include"tree.h"
#include"nut.h"
#include"hoard.h"


Squirrel::Squirrel()
{
	this->nut_carried=0;
	this->skip_factor= 1;
	this->location=NULL;
}
void Squirrel::take_nut()
{
	nut_carried++;	
}
void Squirrel::store_nut(Hoard hoard)
{
	hoard.add_nut();
	nut_carried=NULL;	
}
bool Squirrel::has_nut()
{
	if(nut_carried!=NULL){
		return true;
	}
	else{
		return false;
	}
}
int Squirrel::get_skip_factor()
{
	return skip_factor;
}

void Squirrel::set_skip_factor(int factor)
{
	skip_factor = factor;
}
void Squirrel::set_location(int loco)
{
	location = loco -1;
}
int Squirrel::get_location()
{
	return location;
}
int Squirrel::move_location(int loco, int skip, int num_trees)
{
	location = loco + skip;
	while (location >= num_trees){
		location = location - num_trees;
	}
}



tree.cpp
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
#include"squirrel.h"
#include"tree.h"
#include"hoard.h"
#include"nut.h"
#include <iostream>
Tree::Tree()
{
	this->nuts_left = 20;
}

Tree::~Tree()
{
	delete [] nuts;
}

int Tree::remove_nut()
{
	nuts_left = nuts_left -1;
	
}

int Tree::get_nuts_left()
{
	return nuts_left;
}


hoard.cpp
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
#include <cstddef>
#include<iostream>
#include"squirrel.h"
#include"tree.h"
#include"hoard.h"
#include"nut.h"

Hoard::Hoard()
{
	this->owner = NULL;
	this->number_of_nuts = 0;
}
Hoard::~Hoard()
{
	delete [] nuts;
}
void Hoard::set_owner(Squirrel* name)
{
	owner = name;
}
int Hoard::add_nut()
{
	number_of_nuts = number_of_nuts + 1;
}
int Hoard::get_number_of_nuts()
{
	return number_of_nuts;
}


nut.cpp
1
2
3
4
5
6
7
8
9
10
#include<iostream>
#include"squirrel.h"
#include"tree.h"
#include"nut.h"
#include"hoard.h" 

Nut::Nut()
{
	
}

Last edited on
Someone?
See line 15 of hoard.cpp

Where is nuts ever set to anything?
It is because of the delete in the destructors of tree on the nut array which is uninitialized. Simply adding the initialization of nuts to a null array in the constructor fixes it:

1
2
3
4
5
6
Tree::Tree()
// the initialization of nuts to a null array
: nuts(0)
{
	this->nuts_left = 20;
}


Because when the destructor of Tree is called, the
 
delete [] nuts;


Isn't invalid because it knows it is an empty array. However, without initializing it, it will not know it is an empty array and then it tries to free some memory that was never allocated.

At first glance, you might think the Hoard class has the same issue but since, in main, Hoard is called with a new, the destructor for the allocated Hoard objects isn't ever called because you don't ever call delete on the Hoard objects. Since the Tree object is an automatic variable, that is, it has a scope (of the main function), when the main finishes, the Tree variable goes out of scope and the destructor is automatically called. Thus when the program completely finishes and cleans up the automatic variables at the end when exiting, it calls the destructor of Tree and you get a seg fault because the "nuts" of Tree were never initialized.

In other words, every delete should have a corresponding new and vice versa. New and delete have to do with pointers, which is something many people struggle to wrap their head around right off the bat. When new is called and you make a pointer to the memory location new allocated for your pointer/array, you are essentially removing the variable(s) pointed to by the pointer/array from having a scope and thus why you have to call delete on it when you are done with. In other words, when the program is running, the memory for that variable keeps the same location and value (if you aren't changing it obviously) no matter where you are in the code until deallocate (delete) it. Stepping over how pointers enable polymorphism, that is one of the great advantages of pointers: you can free variables from having a scope and pass them around and make copies of the pointer and change the value at the memory location wherever you want in the code and all the other copies of the pointer will see the effect because all a pointer does is identify a certain location in memory you put a variable and if you modify what is AT that location in memory all the other copies of the pointer "see" it. A C-style array is just a pointer to the start of the memory block where you allocated several memory slots of the size of the class, i.e. a C-style array of doubles of size 10 ( double* myarray = new double[10] ) is a pointer to a block of 80 bytes (each double is 8 bytes X 10 elements = 80 bytes).
Topic archived. No new replies allowed.