Can't get a class member function to display an array

I'm having something of an odd issue. I have a for loop within a class member function that does.not.display.anything. I try to get it to iterate through an array, and it shows nothing. I put other statements in it, and nothing. I manually display elements of the same array OUTSIDE of the for loop, and it displays just fine. I have no idea what I'm missing, though I suspect the answer is both obvious, and embarassing.

The issue itself is in the function display_dimensions(), line 85 in my header file Exception.h, which is in this post. I call it in my main function, line 36, third post down.

General idea of my program: it's an exercise to demonstrate exception handling. I take a number of sides from a user, get dimensions of those sides, and calculate the area. The main program isn't finished yet, I'm still testing as I go. Where I'm stuck is when I enter 4 as the number of sides and then enter in values that aren't the same (to violate rules of a square) to test my exception. check_dimensions() throws an exception which is an object of Exception::BadSquare type. When the exception is thrown, a pointer to the array containing the bad dimensions is passed to the object. I then use the member function display_dimensions() to display the array within the catch block for the BadSquare exception. Nothing in the for loop displays. And yet, outside of the for loop, I can just ask it to show every individual element of the array via hardcoded subscripts, and it works fine.

Here's my header file, Exception.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
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
#include <iostream>
using namespace std;

//Function prototypes from Area.cpp
int get_sides();
float *get_dimensions(int side_count);
double calc_area(double radius);
double calc_area(double side1, double side2, double side3);
double calc_area(double side1, double side2, double side3, double side4);
void display_array(float *arrptr, int size);
void check_dimensions(float *arrptr, int size);

class Exception{

	public:
		class BadSide {
			private:
				int val;	//Stores any bad side numbers for processing (displaying in error message, etc.)
			public:
				//Overloaded constructor to store bad number of sides in member variable val
				BadSide(int s) {
					val = s;
				}

				//Inline function to rturn the bad value stored within member variable
				int get_val() {
					return val;
				}
		};

		class InvalidVal {
			private:
				float*objptr;	//Stores any invalid numbers for processing (displaying in error message, etc.)
			public:
				//Overloaded constructor to store bad number of sides in member variable val
				InvalidVal(float v) {
					
				}

				//Inline function to rturn the bad value stored within member variable
				float get_val() {
					
				}
		};

		class BadTriangle {
			private:
				float *objptr;	//Pointer to an array of bad values
				int size;		//Size of array of bad values
			public:
				//Overloaded constructor to assign member pointer to the address of an array of bad side dimensions
				BadTriangle(float *badptr, int size) {
					////TESTCOUT
					cout << "Now calling badtriangle consructor" << endl;

					objptr = badptr;
				}

				//Inline function to display the bad values stored the array of dimensions
				void display_dimensions() {
					for (int i = 0; i < size; i++)
						cout << objptr[i] << " ";
				}
		};

		class BadSquare {
		private:
			float *objptr;	//Pointer to an array of bad dimensions
			int size;		//Size of array of bad dimensions
		public:
			//Overloaded constructor to assign member pointer to the address of an array of bad side dimensions
			BadSquare(float *badptr, int size) {
				////TESTCOUT
				cout << "Now calling BadSquare consructor" << endl;
				cout << "value of size is " << size << endl;

				objptr = badptr;
			}

			//Inline function to display the bad values stored the array of dimensions
			void display_dimensions() {

				//***** HERE'S WHERE I HAVE THE ISSUE ******
				//This won't display anything
				for (int i = 0; i < size; i++) {
					cout << "Displaying from INSIDE the for loop: " << endl;
					cout << objptr[i];
				}
				//But for some reason, if I display it via hardcoded subs outside of the for loop, it will display all the values in the array just fine
				cout << "Displaying from OUTSIDE the for loop: " << endl;
				cout << objptr[0] << " " << objptr[1] << " " << objptr[2] << " " << objptr[3] << endl;
			}
		};

};

Last edited on
Here's my implementation file Area.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
#include "Exception.h"
	//Includes interface file which contains function declarations/prototypes
	//NOTE: when moving code into embedded compiler, you will need to change the file location string
#include <cmath>	//Needed for pow and sqrt functions
#include <iostream>
using namespace std;

//*******************************************
//Function to get number of sides from user *
//*******************************************

int get_sides() {
	int side_count;

	//Obtain number of sides
	cout << "Enter the number of sides: ";
	cin >> side_count;

	//If answer is zero, assign 1 as number of sides; this will cause the SIDE loop further down to correctly obtain the number of sides
	if (side_count == 0)
		side_count = 1;

	//Throw an exception if the side count is not 1, 3, or 4
	//Note, this exception will also capture 0 or negative values, so no separate exception is needed for those values
	if (side_count != 1 && side_count != 3 && side_count != 4)
		throw Exception::BadSide(side_count);	//Use parameterized constructor to store bad value within exception object
	
	return side_count;
}

//***********************************************
//Function to get dimensions of sides from user *
//***********************************************

float *get_dimensions(int side_count) {

	//Try/catch construct to catch a bad_alloc as a result of allocating a dynamic array
	try {
		//Allocate an array equal to the number of sides entered
		float *ptr = new float[side_count];

		//SIDE loop to obtain length of each side
		for (int count = 0; count <= (side_count - 1); count++)	//Loop will iterate as many times as there are sides, to obtain length of all sides
		{
			//Obtain dimensions of number of sides indicated by user
			cout << "Enter the dimension of side " << count + 1 << ": ";
			cin >> ptr[count];
		}

		return ptr;

	}	//end of try block
	catch (bad_alloc) {
		//Because this try/catch construct is a nested try/catch inside of the test driver file that calls this function, this catch will rethrow
			//the exception to be handled in the outer catch block in the test driver; this way, all exceptions are handled in main for simplicity
		throw;	//Rethrow exception to outer catch block
	}
}

//*****************************************************************************************
//Function to test array of dimensions and throw exception depending on issue encountered *
//*****************************************************************************************

void check_dimensions(float *arrptr, int size) {

//******************  Invalid value exception  ******************
	//Check array of sides for invalid values (0 or negative)
	for (int i = 0; i < size; i++) {
		if (arrptr[i] <= 0)
			throw Exception::InvalidVal(arrptr[i]);
	}

//******************  Illegal triangle exception  ******************

	bool illegal = false;	//Flag used to validate dimensions in ensuing code

	//If user indicated 3 sides (triangle), and any of the side dimensions are illegal (substracting side from the half perimeter yields a negative number), 
		//throw an exception
	if (size == 3) {
		//Calculate half perimeter as sum of all sides divided by 2
		float half_peri = 0;
		for (int i = 0; i < size; i++)
			half_peri += arrptr[i];

		//Check that no side substracted from the half_perimeter yields 0 or a negative number
		illegal = false;	//Initialize illegal flag to false
		for (int i = 0; i < size; i++) {
			if (((half_peri / 2.0f) - arrptr[i]) <= 0)
				illegal = true;
		}

		//Throw exception if the illegal flag is true
		if (illegal)
			throw Exception::BadTriangle(arrptr, size);	//Pass address of array containing bad dimensions to exception object
	}	

//******************  Illegal square exception  ******************
	//If user indicated 4 sides (square), and any sides don't match, throw an exception
	if (size == 4)
	{
		//Confirm that dimensions of all sides are equal
		//IMPT: upper bound must be the number of sides - 1, in order to avoid an off by one error
		for (int i = 0; i < (size - 1); i++) {
			if (arrptr[i] != arrptr[i + 1])
				illegal = true;
		}

		//Throw exception if the illegal flag is true
		if (illegal)
			throw Exception::BadSquare(arrptr, size);	//Pass address of array containing bad dimensions to exception object
	}	
}
And here's my main test driver file, Exception_test.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
#include "Exception.h"
#include <iostream>
using namespace std;

int main() {

	bool validate = true;	//Flag to indicate whether try/catch construct needs to repeat again to correct any exceptions
	int num_sides;
	float *sideptr = nullptr;
	float area;

	//Obtain number of sides
	//While loop is used to repeat process until no exception is thrown
	while (validate) {
		try {
			num_sides = get_sides();
			validate = false;
		}
		catch (Exception::BadSide obj) {
			cout << obj.get_val() << " is an invalid number of sides" << endl;
			cout << "Please enter a valid number of sides" << endl;
		}
	}
	
	//Obtain dimensions of sides, and check them for exceptions
	//While loop is used to repeat process until no exception is thrown
	validate = true;	//Set validate back to true to enter while loop
	while (validate) {
		try {
			sideptr = get_dimensions(num_sides);
			check_dimensions(sideptr, num_sides);
			validate = false;
		}
		catch (Exception::BadSquare obj) {
			cout << "Error, the dimensions entered are invalid: ";
			obj.display_dimensions();    //THIS IS THE FUNCTION CALL WHERE THE FOR LOOP WON'T DISPLAY
			cout << endl << "The sides of a square must all be the same.  Please enter the sides again" << endl;
		}
		catch (Exception::BadTriangle obj) {
			cout << "Error, this is not a legal triangle.  Please enter the sides again" << endl;
		}
		catch (Exception::InvalidVal obj) {
			cout << "Error, sides cannot be 0 or negative.  Please enter the sides again" << endl;
		}
		catch (bad_alloc) {
			cout << "Error, not enough memory" << endl;
			break;	//Need to break the while loop to continue the program, rather than forcing program to continue to allocate memory repeatedly
		}

	}

	delete sideptr;
	sideptr = nullptr;

	return 0;
}


Here's a sample output. I enter 4 as the number of sides, then enter 4 dimensions that aren't the same in order to trigger the BadSquare exception. As you can see, when I call the display_dimensions() function, it doesn't display anything inside of the for loop.

Enter the number of sides: 4
Enter the dimension of side 1: 1
Enter the dimension of side 2: 2
Enter the dimension of side 3: 3
Enter the dimension of side 4: 4
Now calling BadSquare consructor
value of size is 4
Error, the dimensions entered are invalid: Displaying from OUTSIDE the for loop:
1 2 3 4

The sides of a square must all be the same.  Please enter the sides again
Enter the dimension of side 1:

Last edited on
Topic archived. No new replies allowed.