I have a question about dynamic allocation of memory in c++ - c++

I'm new to c++ and I can't understand something in dynamic allocation.
why does the following program build but gives an error and stops?
#include <iostream>
using namespace std;
int main()
{
int amount;
int *p = new int[amount];
cout << "enter the size of array" << endl;
cin >> amount;
for(int i = 0; i < amount ; i++)
{
cout << "enter the " << i + 1 << " number" << endl;
cin >> p[i];
}
for(int i = 0; i < amount ; i++)
{
cout << "number " << i + 1 << " is : " << p[i] << endl;
}
delete []p;
}

You are trying to use amount before you have assigned any value to it. You need to read the user's input for amount first, THEN allocate using it. Not the other way around.
#include <iostream>
using namespace std;
int main()
{
int amount;
cout << "enter the size of array" << endl;
cin >> amount;
int *p = new int[amount];
for(int i = 0; i < amount ; i++) {
cout << "enter the " << i + 1 << " number" << endl;
cin >> p[i];
}
for(int i = 0; i < amount ; i++) {
cout << "number " << i + 1 << " is : " << p[i] << endl;
}
delete[] p;
}

Related

Output does not include all input for my array

I have this program that is barely started:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <string>
using namespace std;
class Grade
{
public:
string studentID;
int userChoice = 0;
int size = 0;
double* grades = new double[size]{0};
};
void ProgramGreeting(Grade &student);
void ProgramMenu(Grade& student);
string GetID(Grade& student);
int GetChoice(Grade& student);
void GetScores(Grade& student);
int main()
{
Grade student;
ProgramGreeting(student);
ProgramMenu(student);
}
// Specification C1 - Program Greeting function
void ProgramGreeting(Grade &student)
{
cout << "--------------------------------------------" << endl;
cout << "Welcome to the GPA Analyzer! " << endl;
cout << "By: Kate Rainey " << endl;
cout << "Assignment Due Date: September 25th, 2022 " << endl;
cout << "--------------------------------------------" << endl;
GetID(student);
cout << "For Student ID # " << student.studentID << endl;
}
void ProgramMenu(Grade &student)
{
cout << "--------------------------------------------" << endl;
cout << setw(25) << "Main Menu" << endl;
cout << "1. Add Grade " << endl;
cout << "2. Display All Grades " << endl;
cout << "3. Process All Grades " << endl;
cout << "4. Quit Program." << endl;
cout << "--------------------------------------------" << endl;
GetChoice(student);
}
string GetID(Grade &student)
{
cout << "Enter the student's ID: ";
cin >> student.studentID;
if (student.studentID.length() != 8) {
cout << "Student ID's contain 8 characters ";
GetID(student);
}
return student.studentID;
}
int GetChoice(Grade &student)
{
cout << "Enter your selection: ";
cin >> student.userChoice;
if (student.userChoice == 1) {
GetScores(student);
}
else if (student.userChoice == 2)
{
}
else if (student.userChoice == 2)
{
}
else if (student.userChoice == 4)
{
exit(0);
}
else
{
cout << "Please enter 1, 2, 3 or 4" << endl;
GetChoice(student);
}
}
void GetScores(Grade &student)
{
int count = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# "
<< student.studentID << "? ";
cin >> student.size;
while (count != student.size) {
cout << "Enter a grade: ";
cin >> score;
for (int i = 0; i < student.size; i++) {
student.grades[i] = score;
}
count++;
}
for (int i = 0; i < student.size; i++) {
cout << student.grades[i] << " ";
}
}
I am trying to make sure my array is recording all test scores, but when I output the array in my GetScore function, each element in the array is the same or equal to the last score I entered. For example, if I choose 3 for size and then enter three values of 99.2 86.4 90.1, all three elements will read 90.1.
Why is this happening?
Your Grade class is allocating an array of 0 double elements (which is undefined behavior), and then your GetScores() function does not reallocate that array after asking the user how many scores they will enter, so you are writing the input values to invalid memory (which is also undefined behavior).
Even if you were managing the array's memory correctly (ie, by using std::vector instead of new[]), GetScores() is also running a for loop that writes the user's latest input value into every element of the array, instead of just writing it to the next available element. That is why your final output displays only the last value entered in every element. You need to get rid of that for loop completely.
Try something more like this instead (there are several other problems with your code, but I'll leave those as separate exercises for you to figure out):
class Grade
{
public:
...
int size = 0;
double* grades = nullptr;
};
...
void GetScores(Grade &student)
{
int size = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# " << student.studentID << "? ";
cin >> size;
if (student.size != size) {
delete[] student.grades;
student.grades = new double[size]{0};
student.size = size;
}
for(int i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades[i] = score;
}
for (int i = 0; i < size; ++i) {
cout << student.grades[i] << " ";
}
}
Alternatively:
#include <vector>
...
class Grade
{
public:
...
vector<double> grades;
};
...
void GetScores(Grade &student)
{
size_t size = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# " << student.studentID << "? ";
cin >> size;
student.grades.resize(size);
for (size_t i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades[i] = score;
}
/* alternatively:
student.grades.clear();
for (size_t i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades.push_back(score);
}
*/
for (size_t i = 0; i < size; ++i) {
cout << student.grades[i] << " ";
}
}
I removed my for loop from my while loop.
void GetScores(Grade &student)
{
int count = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# "
<< student.studentID << "? ";
cin >> student.size;
while (count != student.size) {
cout << "Enter a grade: ";
cin >> score;
student.grades[count] = score;
count++;
}
for (int j = 0; j < student.size; j++) {
cout << student.grades[j] << " ";
}
}

How do I get my vector to display 8 integers after entering them? When I do enter 8 integers, it only displays zeros and not what I entered

#include <iostream>
#include <vector>
using namespace std;
int main() {
int val = 8;
vector<int>numVal(val);
unsigned int i;
cout << "Enter " << val << " integers: "<< endl;
for(i = 0; i < numVal.size(); i++)
{
cin >> val;
}
cout << "Congratulations! You entered 8 integers." << endl;
for(i = 0; i < numVal.size(); i++)
{
cout << numVal.at(i)<<" ";
}
return 0;
}
You are initializing the vector with 8 default-valued elements, and then you are ignoring the user's input completely. That is why you are printing zeros.
You need to store the user's input in the vector, either by:
using the vector's operator[] to access the pre-allocated elements:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> numVal(8);
size_t i;
cout << "Enter " << numVal.size() << " integers: "<< endl;
for(i = 0; i < numVal.size(); i++)
{
cin >> numVal[i];
}
cout << "Congratulations! You entered " << numVal.size() << " integers." << endl;
for(i = 0; i < numVal.size(); i++)
{
cout << numVal[i] << " ";
}
return 0;
}
not pre-filling the vector's elements, but using its push_back() method instead:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int val;
vector<int> numVal;
size_t i;
numVal.reserve(8);
cout << "Enter " << numVal.capacity() << " integers: "<< endl;
for(i = 0; i < numVal.capacity(); i++)
{
cin >> val;
numVal.push_back(val);
}
cout << "Congratulations! You entered " << numVal.size() << " integers." << endl;
for(i = 0; i < numVal.size(); i++)
{
cout << numVal[i] << " ";
}
return 0;
}

C++ POINTERS (student * [n] gives the error that array type is not assignable)

#include <iostream>
#include "student.h"
using namespace std;
int main()
{
// inputting the number of students
int n;
cout << "How many students would you like to process?" << endl;
cin >> n;
student* s[n];
string tmp;
double t;
// entering each student details
for (int i = 0; i < n; i++)
{
// dynamically allocating object
s[i] = new student();
cout << "Enter first name for student " << (i + 1) << endl;
cin >> tmp;
s[i]->setFirstName(tmp);
cout << "Enter middle name for student " << (i + 1) << endl;
cin >> tmp;
s[i]->setMiddleName(tmp);
cout << "Enter last name for student " << (i + 1) << endl;
cin >> tmp;
s[i]->setLastName(tmp);
cout << "Enter GPA for student " << (i + 1) << endl;
cin >> t;
s[i]->setGPA(t);
}
double avgGPA = 0;
// printing the student details
cout << "Students:" << endl;
cout << "---------" << endl
<< endl;
for (int i = 0; i < n; i++)
{
cout << s[i]->getFirstName() << " " << s[i]->getMiddleName() << " " << s[i]->getLastName() << " " << s[i]->getGPA() << endl;
avgGPA += s[i]->getGPA();
}
avgGPA /= n;
// printing the average GPA
cout << endl
<< "Average GPA: " << avgGPA;
// freeing the memory allocated to objects
for (int i = 0; i < n; i++)
delete s[i];
return 0;
}
Under the main function student * s [n]; says the array type is not assignable to the line.It also gives an error that the expression must contain a literal. I thought I was doing everything right, but there was an error. What is the solution to this error can anyone help?
student* s[n]; is a Variable-Length Array (VLA), which is not in the standard C++.
You should use std::vector like std::vector<student*> s(n);.
Also add #include <vector> at the beginning of your code to use that.

Printing arrays using for loop in C++

I'm trying to print the value of pointer array using for loop as usual, and I managed to print value stored in one object, but can't print the value stored in another object. My classes are defined in Predmet.h:
#include <iostream>
#include <string>
using namespace std;
class Predmet
{
public:
int numberOfItems;
string name;
Predmet();
~Predmet();
};
and Plaza.h:
class Plaza
{
public:
int length;
double x;
double y;
Plaza();
~Plaza();
};
My main.cpp looks like this:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include "Plaza.h"
#include "Predmet.h"
using namespace std;
int main() {
int n, m;
int *numberOfBeaches;
Plaza *obj1;
Predmet *obj2;
cout << "Enter number of beaches (N): ";
cin >> n;
obj1 = new Plaza[n];
for (int i = 0; i < n; i++) {
cout << "Enter length and coordinates for " << i + 1 << ". beach: " << endl;
cin >> obj1[i].length;
cin >> obj1[i].x >> obj1[i].y;
}
cout << endl;
cout << "Enter number of items (M): ";
cin >> m;
obj2 = new Predmet[m];
numberOfBeaches = new int[n];
for (int i = 0; i < m; i++) {
cout << "Enter ordinal number of beach for " << i + 1 << ". item: ";
cin >> numberOfBeaches[i];
cout << "Enter how much of item you have and name of the item: ";
cin >> obj2[i].numberOfItems >> obj2[i].name;
}
int *p;
for (int i = 0; i < n; i++) {
p = find(numberOfBeaches, numberOfBeaches + n, i + 1);
if (*p == i + 1) {
for (int j = 0; j < m; j++) {
cout << i + 1 << ". " << obj1[i].x << " " << obj1[i].y << " D=" << obj1[i].length << " - predmeti: " << obj2[j].numberOfItems << " " << obj2[j].name << endl;
}
}
else {
cout << i + 1 << ". " << obj1[i].x << " " << obj1[i].y << " D=" << obj1[i].length << " - predmeti: " << endl;
}
}
delete[] obj1;
delete[] obj2;
delete[] numberOfBeaches;
system("pause");
return 0;
}
Everything was working until this point where I add printing for obj2[i].kolicina and obj2[i].opis, I get weird looking result as a print and this exception thrown, as you can see below:
What am I doing wrong? Thanks in advance.
EDIT:
After suggestions in the comments, I managed to fix the code (updated version above) to print it proper way, only when I have M > 1 (e.g. M = 2) I get duplicate printing of lines? How can I fix that?
The problem is with this line:
cout << i + 1 << ". " << obj1[i].x << " " << obj1[i].y << " D=" << obj1[i].duljina << " - predmeti: " << obj2[i].kolicina << " " << obj2[i].opis << endl;
obj2 is being defined as having m elements, yet you are using i, which has the values 0 <= i < n. I don't know what m's relation is to n, but that is certainly where you should start.
obj2contains melements:
obj2 = new Predmet[m];
brojPlaze contains n elements:
brojPlaze = new int[n];
you are looping over all Predmet in obj2:
for (int i = 0; i < m; i++) {
...
}
and inside the loop, you access element i of brojPlaze:
cin >> brojPlaze[i];
but i goes from 0 to m, and m can be greater than the n element brojPlaze contains. thus, you may access an element outside of the array, which can cause a lot of undesired effects...

how to call functions and unused expression error

I get an error saying: use of undeclared identifier 'again'.
I am trying to go from int main to void again and back after getting an answer.
Please explain to me why it won't work also. Thanks.
Here is my full code:
#include <iostream>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <string>
using namespace std;
{
string answer;
cout << "Would you like to enter another set of data? Y or N?" << endl;
cin << answer;
string yes = "Yes";
string no = "No";
if(a == yes)
{
main();
}
}
int main()
{
cout << "Kaitlin Stevers" << endl;
cout << "Exercise 11 - Vectors" << endl;
cout << "November 12, 2016" <<endl;
cout << endl;
cout << endl;
int size;
cout << " How many numbers would you like the vector to hold? " << endl;
cin >> size;
vector<int> numbers;
int bnumbers;
for (int count = 0; count < size; count++)
{
cout << "Enter a number: " << endl;
cin >> bnumbers;
numbers.push_back(bnumbers); // Adds an element to numbers
}
//display the numbers stored in order
cout << "The numbers in order are: " << endl;
for(int bcount = 0; bcount < size; bcount++)
{
cout << numbers[bcount] << " ";
}
cout << endl;
//display the numbers stored reversed
cout << "Here are the numbers in reverse order: " << endl;
reverse(numbers.begin(), numbers.end());
for(int rcount = 0; rcount < size; rcount++)
{
cout << numbers[rcount] << " ";
}
cout << endl;
again();
return 0;
}
void again()
}
You need to declare your fonction "again" before calling it :
#include <iostream>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <string>
using namespace std;
void again();
int main()
{
cout << "Kaitlin Stevers" << endl;
cout << "Exercise 11 - Vectors" << endl;
cout << "November 12, 2016" <<endl;
cout << endl;
cout << endl;
int size;
cout << " How many numbers would you like the vector to hold? " << endl;
cin >> size;
vector<int> numbers;
int bnumbers;
for (int count = 0; count < size; count++)
{
cout << "Enter a number: " << endl;
cin >> bnumbers;
numbers.push_back(bnumbers); // Adds an element to numbers
}
//display the numbers stored in order
cout << "The numbers in order are: " << endl;
for(int bcount = 0; bcount < size; bcount++)
{
cout << numbers[bcount] << " ";
}
cout << endl;
//display the numbers stored reversed
cout << "Here are the numbers in reverse order: " << endl;
reverse(numbers.begin(), numbers.end());
for(int rcount = 0; rcount < size; rcount++)
{
cout << numbers[rcount] << " ";
}
cout << endl;
again();
return 0;
}
void again()
{
string answer;
cout << "Would you like to enter another set of data? Y or N?" << endl;
cin >> answer;
string yes = "Yes";
string no = "No";
if(answer == yes)
{
main();
}
}
However, it's a strange things to use recursivity for what you want to do and to call main func multiple times (which is by definition, main entry of a program). In my opinion, you should call in your main function another function named like askInformation which uses a loop with a test case to know if user wants to add informations or not.