My primary objective right now is to get the program to display the following, when the user presses 1 at the main menu:

Size of 1st pizza order: Small
Topping of 1st pizza order: No topping

Size of 2nd pizza order: Small
Topping of 2nd pizza order: No topping

I think the main culprit is the Order function; but trust me, i've tried several different combination/orders of the statement.

#include <iostream>
#include <string> 
using namespace std;



struct Pizza
{
	string structSize;
	string structTopping;
	//string pizzaRAY[2]; //2 different pizza orders
};

void Order(Pizza * specPtr[], int size);

int main()
{
	int select, size;  //size will refer to the title group user wants to view/modify
	
	string pizzaSize, pizzaTopping;
	
	int pizzaOrder; //generate default values of: Small (size), No topping (topping)

		
	//Pizza * pizzaPtr[2]; //2 different pizza orders
	Pizza * pizzaPtr[2];

	Pizza setup1, *setup2;


	Order(pizzaPtr, -2);

	do {
		cout << "\n1, to see current selection. \n2, to change current selection. \n3, to end program: " << endl;
		cin >> select;

		switch (select)
		{
		case 1:  
			
			pizzaPtr[0] = new Pizza;			
			cout << "Size of 1st pizza order: " << pizzaPtr[0]->structSize ;  
			cout << "\nTopping of 1st pizza order: " << pizzaPtr[0]-> structTopping << endl;
			
			pizzaPtr[1] = new Pizza;
			cout << "Size of 2nd pizza order: " << pizzaPtr[1]->structSize ;
			cout << "\nTopping of 2nd pizza order: " << pizzaPtr[1]->structTopping << endl;
			
			break;
		
		case 2:
			cout << "Enter Pizza order #, you want to change: ";
			cin >> pizzaOrder;

			//pizzaOrder -= 1;  //passed on to Order( , int size)
			
			Order(pizzaPtr, pizzaOrder);	

			break;

		case 3:
			cout << "Thank you for using this program" << endl;
			break;
		}
				
	} while (select != 3);


	system("pause");
	return 0;
}

void Order(Pizza * specPtr[], int size)
{
			
	for (int i = 0; i < size; i++)
	{
		
		Pizza * setPtr;  //call struct Pizza
		setPtr = new Pizza[size];
		Pizza *ptr = &setPtr[0];
		/*if (size < 0)
		{
		
				
		}

		else
		{ */
		int min;
		min = size - 1;
		if (i == min)
		{
		cout << "\nEnter size of of piza: " ;//<< specPtr[size]->structSize;
		cin.ignore();
		getline(cin, (setPtr[i]).structSize);
		cout << "\Enter topping of piza: " ;// << specPtr[size]->structTopping;
		cin.ignore();
		getline(cin, (setPtr[i]).structTopping);
		cout << endl;
		}
		else 
		{
		setPtr[0].structSize = "Small";
		setPtr[0].structTopping = "No topping";

		setPtr[1].structSize = "Small";
		setPtr[1].structTopping = "No topping";	

		}

		
		delete [] setPtr;
	}
		
}

Line 31 -- I fail to see the point of calling this function with a negative size value. It does absolutely nothing.

Line 41 -- Create a new pizza with uninitialized memory.
Lines 42 and 43 -- Display the uninitialized memory. Lord knows what you'll get. I think a string will initialize to an empty string. What you WON'T get is what you say you're going to get...viewing a previously filled in pizza order.
Line 49 -- Memory leak. You never freed the memory from lines 41 and 45.

I could try to figure out what you intended by looking at the commented out code, but suffice it to say, with the code the way it is, you never use specPtr[] in your Order function, so why bother passing it, and all you do in the function is go through a loop asking questions, allocating local memory, then deleting it. None of it will ever make it back to your main function, so what's the point?

So that's what the program actually does... nothing, at best. What's it SUPPOSED to do?

It is supposed to allow users to update 2 information about 2 different pizzas.

1 of which is to update the size (small, medium, large)

2nd is to allow them to enter the kind of topping they want on the pizza.

Then the user can view the latest information on it, by pressing 1 at the main menu.

If the user fails to enter/update any information about the pizza, the default settings will be dispalyed for the user, i.e.

Size of 1st pizza order: Small
Topping of 1st pizza order: No topping

Size of 2nd pizza order: Small
Topping of 2nd pizza order: No topping

Adding delete [] pizzaPtr;
caused the program to crash, when 1 was entered at the main menu.

I have to write the code as pizzaPtr[0] = new Pizza;
rather than pizzaPtr[0]; so that a fatal error doesn't occur.


I have since changed setPtr in the order function to specPtr, the program is operating the same as before. If i can be shown how to get the defauult values

Size of 1st pizza order: Small
Topping of 1st pizza order: No topping

Size of 2nd pizza order: Small
Topping of 2nd pizza order: No topping

When 1 is entered at the main menu, that would be great.

Edited 5 Years Ago by coroshea: n/a

I question the need for new and delete in the program at all. You know the size already. Just declare an array of size 2 statically. It's much easier and dynamic allocation offers no benefit in this program.

If you are REQUIRED to use new and delete, they should be in main, not in your function. You allocate them at the beginning of main, you delete them at the end of main.

Lines 104 to 108 -- You're already in a loop going through all pizzas. No hard-coded indexes should be used. You're working on pizza number i, so use i, not 0 and 1.

I don't see any reason for "min" and the associated code in your function. Again, you're looping through one pizza at a time and changing the order.

You set aside memory for an array of two pizzas like this...

Pizza* pizzas = new Pizza[2];

You also need to add some comments to your functions to explicitly state what the parameters represent. Clearly "size" refers to the NUMBER of pizzas to adjust, yet on line 57, you have this...

Order(pizzaPtr, pizzaOrder);

where pizzaOrder represents the "order number", not the "number of orders".

Might I suggest using a reference to a vector<Pizza> rather than a pointer to an array? It would solve most of the issues revolving around pointers and allocation, I think. I realize that it may not be an option with a school project, but if it is acceptable, it would save a lot of trouble.

For that matter, you could also simplify things by using an enumeration for the size type, and a vector of strings for the toppings:

enum PIZZA_SIZE {SMALL, MEDIUM, LARGE};

struct Pizza
{
    PIZZA_SIZE size;
    vector<string> toppings;
};

Again, this would depend on whether this was covered in your coursework yet or not.

Edited 5 Years Ago by Schol-R-LEA: n/a

Come to think of it, the directions did state something about enumerots.

something like the Case labels should be enumerators name:

enum VIEW EDIT EXIT.

Trust me, I'd use vectors if i could, but the teacher required the use of dynamic allocation in order function for the two struct objects (pizza orders). 1st struct Pizza object is assigned 1st array element, 2nd struct pizza object is the 2nd array element. Default settings of the orders should be ...Smalll ...No topping.

Anyone?

This is what i have, won't display the results of the orders no matter what.

#include <iostream>
#include <string> 
using namespace std;


struct Pizza
{
	string structSize;
	string structTopping;
	//string pizzaRAY[2]; //2 different pizza orders
};

void Order(Pizza * specPtr[], int size);

int main()
{
	int select, size;  //size will refer to the title group user wants to view/modify
	
	//string pizzaSize, pizzaTopping;
	
	int pizzaOrder; //generate default values of: Small (size), No topping (topping)
	Pizza * pizzaPtr[2];

	//Pizza setup1, *setup2;
		

	Order(pizzaPtr, -2);

	do {
		cout << "\n1, to see current selection. \n2, to change current selection. \n3, to end program: " << endl;
		cin >> select;

		switch (select)
		{
		case 1:  
			
			pizzaPtr[0] = new Pizza;			
			cout << "Size of 1st pizza order: " << pizzaPtr[0]->structSize ;  
			cout << "\nTopping of 1st pizza order: " << pizzaPtr[0]-> structTopping << endl;
			
			pizzaPtr[1] = new Pizza;
			cout << "Size of 2nd pizza order: " << pizzaPtr[1]->structSize ;
			cout << "\nTopping of 2nd pizza order: " << pizzaPtr[1]->structTopping << endl;
			
			//delete [] pizzaPtr;

			break;
		
		case 2:
			cout << "Enter Pizza order #, you want to change: ";
			cin >> pizzaOrder;

			//pizzaOrder -= 1;  //pizza order they want to modify
			
			Order(pizzaPtr, pizzaOrder);	//pass 1 for order 1

			break;

		case 3:
			cout << "Thank you for using this program" << endl;
			break;
		}
				
	} while (select != 3);


	system("pause");
	return 0;
}

void Order(Pizza * specPtr[], int size)
{
			
	for (int i = 0; i < size; i++)
	{

		
		Pizza * specPtr;  //call struct Pizza
		specPtr = new Pizza[2];
		//specPtr = new Pizza[size];
		
		int min;
		min = size - 1;
		if (i == min && min >= 0)
		{
		cout << "\nEnter size of of piza: " ;
		cin.ignore();
		getline(cin, (specPtr[i]).structSize);
		cout << "\Enter topping of piza: " ;
		cin.ignore();
		getline(cin, (specPtr[i]).structTopping);
		cout << endl;
		}
		else 
		{
		specPtr[0].structSize = "Small";
		specPtr[0].structTopping = "No topping";
 
		specPtr[1].structSize = "Small";
		specPtr[1].structTopping = "No topping";
		}
				
		delete [] specPtr;
	}
		
}

There are a number of issues which I can see with this, mostly relating to the dynamic memory allocation. Let's walk through the current workflow and it should show where the problems lie.

First, in main() , you declare pizzaPtr as an array of two pointers to type Pizza . you do not initialize this array before calling Order() with pizzaPtr as an argument.

In Order() , you are passed the pointer specPtr . Then, inside the for() loop, you re-declare specPtr , causing the argument to be masked by a local variable. This local specPtr is then initialized, set, and then discarded, with no effect being made on the argument version of specPtr .

Once back in main() , you then attempt to initialize pizzaPtr[0] with a new Pizza object, then print out the newly created Pizza object. You do the same for pizzaPtr[1] .

Does this make things a bit clearer?

I think what you will want to do is initialize the two elements of pizzaPtr before passing pizzaPtr to Order() .

This article has been dead for over six months. Start a new discussion instead.