need help figuring out why program is crashing.

Hi, I am trying to dynamically allocate memory in my code. For some reason my program crashes when entering a quantity and says I have hit a break point and brings up debug_heap.cpp. it always brings me to around line 340 to 370 and in there talks about error bad memory allocation: bad memory block type. Also in there is talks about no_mans_land_size. I am still very new to C++ so I am kind of lost in trying to figure out what I am doing wrong. If anyone can help it would be greatly appreciated. Thank you in advance for any help. my current code is below.

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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
  #include <iostream>
#include <string>
#include <string.h>
using namespace std;

//menu
void displayProducts()
{
	int total;
//array for quantity
	int quantity[3];
	int i;
	for (i = 0;i < 3; i++)
		quantity[i] = 0;
	char selection = 'a';
	do
	{
//trying to dynamically allocate memory for products array while for the first element 
//in the array having the user imput the first item name and dynamically allocating 
//that element based upon the size of the name the user imputs
		string * products;
		products = new string[3];
		char temp[100];
		cout << "enter the first product name" << endl;
		cin >> temp;
		int len = strlen(temp) + 1;
		char * newProduct = new char[len];
		strcpy_s(newProduct, 100, temp);
		products[0] = newProduct;
		products[1] = "oranges";
		products[2] = "bananas";
		cout << "you entered " << products[0] << endl;
		cout << "The list of products are below" << endl;
		cout << "product 1:" << products[0] << endl;
		cout << "product 2:" << products[1] << endl;
		cout << "product 3:" << products[2] << endl;



/* previous array for products
		string products[3] = { "Apples", "Bananas", "Oranges" };
		cout << "Menu====== " << endl;
		*
		for (int i = 0; i < 4; i++)
		{
			cout << "Product " << i + 1 << ": " << products[i] << endl;
		}
*/
		cout << "Press 4 to proceed to order summary." << endl << endl;
		cout << "Enter selection: ";
// read user selection
		cin >> selection;
// program crashes when entering quantity?
		switch (selection)
		{
		case '1':
			cout << "You selected - " << products[0] << endl;
			cout << "Please enter quantity. ";
			cin >> quantity[0];
			break;

		case '2':
			cout << "You selected - oranges" << endl;
			cout << "Please enter quantity. ";
			cin >> quantity[1];
			break;

		case '3':
			cout << "You selected - bananas" << endl;
			cout << "Please enter quantity. ";
			cin >> quantity[2];
			break;

		case '4':
			cout << "Thank you." << endl;
			break;

			//if  1, 2, 3 or 4 is not selected then go to the default case
		default: cout << "Invalid selection. Please try again";
			// no break in the default case
		}
		cout << endl << endl;
		delete [] products;
	} while (selection != '4');

	cout << "\nYou ordered " << quantity[0] << " Apples" << " for a cost of $" << quantity[0] << endl;
	cout << "You ordered " << quantity[1] << " Bananas" << " for a cost of $" << quantity[1] << endl;
	cout << "You ordered " << quantity[2] << " Oranges" << " for a cost of $" << quantity[2] << endl;
	//using the quantity array to calculate total
	total = (quantity[0] + quantity[1] + quantity[2]);
	cout << "Your grand total is $" << total << endl;
	cin.get();
}
// Customer class
class Customer
{
	string name;
	string address;
public:
	void setName(string);
	string getName();
	void setAddress(string);
	string getAddress();
};
// Function definitions of customer class
void Customer::setName(string name1)
{
	name = name1;
}
void Customer::setAddress(string address1)
{
	address = address1;
}
string Customer::getName()
{
	return name;
}
string Customer::getAddress()
{
	return address;
}
//main
int main()
{
	Customer a;
	string name;
	string address;
	cout << "Please enter your name." << endl;
	getline(cin, name);
	cout << "Please enter your address." << endl;
	getline(cin, address);
	cout << "hello " << name << ", please press enter when you are ready to move on to the list of products" << endl;
	cin.get();
	char selection = 'a';
	displayProducts();

	cin.get();
	return 0;
}
I'd recommend against using C-strings when you can use std::string; you've even included the string header. I haven't fully read your code yet, but at least change it so that you're using std::string. It will make your life much easier and your code easier to maintain and debug.
Okay I have updated to
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 string * products;
		products = new string[3];
		string temp;
		cout << "enter the first product name" << endl;
		cin >> temp;
		int len = sizeof (temp) + 1;
		string * newProduct = new string[len];
		temp = *newProduct;
		products[0] = *newProduct;
		products[1] = "oranges";
		products[2] = "bananas";
		cout << "you entered " << products[0] << endl;
		cout << "The list of products are below" << endl;
		cout << "product 1:" << products[0] << endl;
		cout << "product 2:" << products[1] << endl;
		cout << "product 3:" << products[2] << endl;


now the program doesn't crash but however when entering the first product name during the program the name doesn't show up and is just blank. Am I missing or doing some thing wrong with *newProduct?
int len = sizeof (temp) + 1;
This won't work how you think it will. For example,
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <string>

int main()
{
    std::string empty{}, str{ "Hello World" };
    std::cout << "size of empty = " << sizeof( empty ) << '\n'
              << "size of str = " << sizeof( str ) << '\n';
}


size of empty = 8
size of str = 8

Instead use std::string's member function length().
http://www.cplusplus.com/reference/string/string/length/

Instead of dynamically allocating memory, use a std::vector.
pleaseINeedHelp,

The following are the instructions for your assignment, are they not? I found them on your other thread:

"For the products, use an array of pointers to strings, and dynamically allocate space for each of the strings. To fill in the products array, read one product name from the user, check the length, and then allocate memory based on the length of the entered word."


Note: the assignment is asking for an array of pointers to strings. You have a string pointer that points to an array of strings.

Also, using sizeof to determine the length of a string will never do what you think it's doing.

Not exactly sure what your instructor means by "check the length, and then allocate memory based on the length of the entered word". std::string's are designed with shrinking and growing in mind. Could it be that she/he wants you to use C-Strings?

xismn, you are correct that was a previous thread of mine and yes those are the directions of the assignment. I tried asking my instructor to explain more but have yet to get an email back from him, which is why I am here. I'm not sure what the difference is between an array of pointers to strings and what you said I have, a string pointer to an array of strings. The given example for that is this
1
2
3
 
char Temp[100]; // to hold the entry
char * products [100]; // to hold the products  

Also you may be correct in saying that the instructor wants me to use C-Strings because the example is:
1
2
3
4
5
cin >> Temp;// to get the product 
int len = srtlen(Temp) +1 ;//to determine the length of the product name
char * newProduct = new char[len];//to allocate memory
strcpy(newProduct, Temp);//to copy the entry to a new product
products[0] = newProduct;//to save in the array  

Which is why I used C-String in my original code. Though that is the example the assignment doesn't say I have to use C-Strings explicitly. My school is online so I am basically trying to teach myself most everything.
I have also update my code to use temp.length() instead of sizeof.
1
2
3
4
5
6
7
8
9
10
11
12
string * products;
		products = new string[3];
		string temp;
		cout << "enter the first product name" << endl;
		cin >> temp;
		int len = temp.length() + 1;
		string *newProduct = new string[len];
		temp = *newProduct;
		products[0] = *newProduct;
		products[1] = "oranges";
		products[2] = "bananas";
		cout << "you entered " << products[0] << endl;

Though I am still having the problem of user input not showing up when the program is running.
pleaseINeedHelp,

Here is an example of what you have (more or less) - a string pointer which points to an array of strings (the string pointer is stored in stack memory, and the array of strings is stored in heap memory):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <string>

int main() {

	using string = std::string;
	using string_pointer = string*;
	using integer = int;

	const integer number_of_strings = 3;

	string_pointer strptr = new string[number_of_strings];

	delete[] strptr;
	return 0;
}


Now, here is an example of an array of string pointers (the array of string pointers is stored in stack memory, and the strings being pointed to are stored in heap memory):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <string>

int main() {

	using string = std::string;
	using string_pointer = string*;
	using integer = int;

	const integer number_of_strings = 3;

	string_pointer array[number_of_strings] = { nullptr };

	for (integer i = 0; i < number_of_strings; ++i) {
		array[i] = new string;
	}

	for (integer i = 0; i < number_of_strings; ++i) {
		delete array[i];
		array[i] = nullptr;
	}

	return 0;
}


Don't let the heap and stack memory stuff confuse you too much, I'm just being very explicit.
Unless your instructor taught you the difference, it's very likely that they just weren't being precise in their assignment instructions, and that they do actually want you to allocate an array using new[] (as you have done).

However, I'm certain at this point that your instructor wants you to use C-strings. The instructions say that you must allocate memory based on how long the string is, which is something you do not have to do with std::string's, as they are designed to shrink and grow by themselves. This only really applies to C-strings, since they are basically just character arrays, which is why I think you must use them (and, by extension, you mustn't mix C-strings and std::string's).
Last edited on
Topic archived. No new replies allowed.