Some weird exception throws - c++

The strange problem appears in my program. It is working, but in debugging it shows the "Exception thrown" in random places at the outputting
cout<<"Average value:"<<u3.apr();
_getch();
Sometimes, it even throws this error after the main function (Behind the {})
It is quite annoying because the program just closes after 3 seconds because of these errors.
(Maybe that's because of class, but I'm trying to learn it ;) )
Have tried already changing lines order, rewriting class name and array name.
#include <iostream>
#include <conio.h>
using namespace std;
class vid
{
private:
int i, j;
double rez, sum=0;
public:
int size;
double *arr = new double[size];
double apr()
{
for (i = 0; i < size; i++)
{
sum += (*(arr + i));
}
return sum / size;
}
};
int main()
{
vid u3;
cout << "Enter array length:";
cin >> u3.size;
for (int i = 0; i < u3.size; i++)
{
cout << "Enter array's " << i << " element:" << endl;
cin >> *(u3.arr+i);
}
cout << "Your array:" << endl;
for (int i = 0; i < u3.size; i++)
{
cout << *(u3.arr + i) << "\t";
}
cout << endl;
cout<<"Average value:"<<u3.apr();
_getch();
}
Thanks for any help ;)

arr is initialised when u3 is constructed.
But you didn't populate u3.size until later.
So, your array has indeterminate length (which is already UB), and your accesses later may be invalid.
You're going to have to manage your class's member a bit more cleverly!
Such classes generally have a "resize" function that performs the allocation per the requested size. Don't forget to safely kill any prior allocation, transplanting data if necessary. You can find online plenty of examples of a vector implementation.
Certainly renaming classes and randomly re-ordering the lines of your program's source code is not going to solve anything.

u3.size is not set until after u3 is constructed. By setting u3.size you can avoid this compiler-time error.
It seems that as an alternative solution, you might want to consider how to get rid of the new call and the need to write a destructor that will delete arr.
By creating a constructor that takes a size parameter AND by switching arr to a std::vector, you can allow the class to hold the vector and handle memory allocation and deallocation:
#include <iostream>
#include <vector>
using namespace std;
class vid
{
private:
int i, j;
double rez, sum=0;
public:
int size;
std::vector<double> arr;
// constructor requires size to be passed in;
// constructor initializes the arr array with the passed in size to zeroes.
vid(int argSize) : size(argSize), arr(argSize, 0.0){ }
double apr()
{
for (i = 0; i < size; i++)
{
sum += arr[i];
}
return sum / size;
}
};
int main()
{
uint size;
cout << "Enter array length:";
cin >> size;
vid u3(size);
for (int i = 0; i < u3.size; i++)
{
cout << "Enter array's #" << i << " element:" << endl;
cin >> u3.arr[i];
}
cout << "Your array:" << endl;
for (int i = 0; i < u3.size; i++)
{
cout << u3.arr[i] << "\t";
}
cout << endl;
cout<<"Average value:"<<u3.apr();
char ch;
cin >> ch;
}

Related

How to create an array that matches the students name with their score?

#include <iostream>
#include <array>
#include <algorithm>
void *swap(int arr[], int size);
void *swap(int arr[], int size) {
int i,j,temp;
for(int i{0}; i < size; i++) {
for(int j{i+1}; j < size; j++) {
if(arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
std::cout <<"The numbers in ascending order are: ";
for(int i{0}; i < size; i++)
std::cout << arr[i] << " ";
}
void average_score(int arr[], int size);
void average_score(int arr[], int size) {
int average {0};
for(int i{0}; i < size; i++) {
average+=arr[i];
}
std::cout << "\nThe average is: " << average / size << std::endl;
}
int main() {
int *test_scores = nullptr;
int n;
std::cout <<"Enter Size: ";
std::cin >> n;
test_scores = new int[n];
int i = 0;
int student_scores;
while(i < n) {
std::cout << "Enter Student " << i+1 << " Test Score: ";
std::cin >> student_scores;
test_scores[i] = student_scores;
i++;
}
swap(test_scores,3);
average_score(test_scores,3);
}
The assignment is also asking me to instead of stepping through the arrays, use pointers rather than array subscripts. I have already created a program where it takes in the test scores and calculates the average and sorts it into ascending order, now I just need to create a display of the student's name right next to their score. Any thoughts or helpful advice that I can use to help me build this program?
In C++ you have a data container called struct that may help you with that. (You can also use classes, but I don't think they are necessary here).
A possible struct for this problem may be declared like this:
struct student {
int grade;
string name;
};
In your main program you could change the test_scores array for a vector, which is more helpful as its size can be modified.
std::vector<student> test_scores(n);
If you want to access the attributes of your student struct you would do so by using the dot operator.
int a = test_scores[0].grade;
string s = test_scores[0].name;
You are given this error because you try to add an int into a student vector. "no matching function call" means that the compiler does not know how to transform the integer into a student. To fix it, I recommend you to ask for the name instead of only asking for the score, so you may add the following code:
student s;
for (int i = 0; i < n; ++i) {
std::cout << "Enter Student " << i+1 << " Name and Test Score: " << endl;
std::cin >> s.name >> s.grade;
test_scores[i] = s; // Don't use test_scores.push_back(s) here, if you do so,
// you would increase its size by 1 and add the element s at the end of the vector.
}
In your average_score function, you should change the int arr[] parameter for a vector <student> &arr and average += arr[i] for average += arr[i].score. The & in &arr is important because it passes the parameter as reference so that its elements are not copied into the function, which is very unnefficient.
Your swap function should be void instead of void *. Also, try using the sort function of the algorithm library. The sorting code you implemented has quadratic cost over the vector length, which is very unefficient if you have a lot of students.

How to end a user input array

So this is for a lab assignment and I already have it working, but one thing is bothering me. The assignment involves creating a 1-dimensional array and then manipulating it. I am supposed to allow a max of 100 inputs but the user does not have to use all 100. Right now, I am using a while statement to either break or allow another input to be entered. To break the statement, you have to enter a negative number (this is what I don't like and want to change). What other options are there to end the user input, once they are done entering their numbers? Is it possible to end the loop once you hit enter with nothing typed?
I have searched stackoverflow for the last 3 days and found some compelling stuff but could never get it to work.
Note, I get the void function is redundant here but that's besides the point (unless it actually affects my ability to achieve what I want).
Also, thanks in advance.
here is my code so far (my while statement is in the main)... be kind I'm a newbie to coding.
#include <iostream>
using namespace std;
void reverseElements(int array[], int size)
{
int tmp;
int j;
int i = size;
j = i - 1;
i = 0;
while (i < j)
{
tmp = array[i];
array[i] = array[j];
array[j] = tmp;
i++;
j--;
}
cout << "I will now reverse the elements of the array." << endl;
cout << endl;
for (i = 0; i < size; i++)
{
cout << array[i] << " " << endl;
}
}
int main()
{
const int NUM_ELEMENTS = 100;
int iArr[NUM_ELEMENTS];
int i;
int myInput;
cout << "Enter your numbers, then enter a negative number to finish" << endl;
cout << endl;
for (i = 0; i < NUM_ELEMENTS; i++) //loop to obtain input
{
cin >> myInput;
if (myInput < 0) //checks for negative number to end loop
{
break;
}
else //continues to allow input
{
iArr[i] = myInput;
}
}
cout << endl;
reverseElements(iArr, i);
return 0;
}
Probably the easiest solution: let your user choose how many numbers to write before actually writing them.
int readNumbersCount()
{
int const numbersMin = 1;
int const numbersMax = 100;
int numbersCount = -1;
while (numbersCount < numbersMin || numbersCount > numbersMax)
{
std::cout <<
"How many numbers are you going to enter? Choose from " <<
numbersMin << " to " << numbersMax << ":\n";
std::cin >> numbersCount;
}
return numbersCount;
}
int main()
{
int const numbersCount = readNumbersCount();
for (int i = 0; i < numbersCount; ++i)
{
// read the numbers etc.
}
return 0;
}
I wrote readNumbersCount() as a separate function to extract numbersMin and other "one-use" identifiers from main() and to make main()'s numbersCount const.
I have edited the main function a little bit.
Here the user is asked how many elements he wants to enter .
and doing the memory allocation dynamically so as to save space
int main()
{ int n=101;
while(n>100){
cout<<"How many numbers do you want to enter";
cin>>n;
}
int *ptr=new(nothrow)int[n];
for (int i=0;i<n;i++){
cout << "Enter your number" << endl;
cin>>ptr[i];
}
cout << endl;
reverseElements(ptr, n);
return 0;
}

How can I input data to array and print them through function?

I am trying to input data to an array and then print them by using a function but I am not sure how to organize the code.
#include <iostream>
using namespace std;
void showGrade(double grade[], int size);
int main()
{
double grade[];
int size;
for (int i = 0; i < size; i++)
{
cout << "Please enter the number of grade" << endl;
cin >> size;
}
showGrade(grade, size);
return 0;
}
void showGrade(double grade[], int size) //How many grade we have
{
for (int counter = 0; counter < size; counter++)
{
cout << "Please enter your grades: " << endl;
cin >> grade[counter];
cout << "Here are your grades: " << endl;
}
}
I Expect to see how many grades I input and then show them.
UPDATE 8/28/19
I figured out how to do it in main function successfully. But what I really want is to put them in a seperate function. My new codes have error at the function call which is type name is not allowed and expected a ')'. How do I make it work?
#include <iostream>
using namespace std;
void showGrades(double ar[], int size);
int main()
{
double ar[20];
int size;
showGrades(double ar[size], int size);
system("pause");
return 0;
}
void showGrades(double ar[], int size) {
cout << "Please enter the number of grade "; // array size
cin >> size;
cout << "Please enter your grades " << endl;
for (int i = 0; i < size; i++) {
cin >> ar[i];
}
cout << "The grades you entered are: " << endl;
for (int i = 0; i < size; i++) {
cout << ar[i] << endl;
}
}
First of all, you need to use the standard container
std::vector
instead of the double grade[];, since you want a variable-length
array as per user input.
Secondly, you are using un-initialized size variable in
for (int i = 0; i < size; i++)
hence it will be initialized with a garbage value. There you need no for-loop
A good starting would be:
#include <iostream>
#include <vector> // std::vector
void showGrade(std::vector<double>& grade)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -> pass the vector by ref, as the grades should be inseted to the it
{
// the logic
}
int main()
{
int size;
std::cout << "Please enter the number of grade" << endl;
std::cin >> size;
std::vector<double> grade;
grade.reserve(size); // reserve memory for unwanted re-allocations
showGrade(grade);
return 0;
}
I leave it to you to complete, after reading about the std::vector more.
Also, do not practice with using namespace std;. Read more:
Why is "using namespace std;" considered bad practice?
this is not a valid C++ code:
double grade[];
You can use std::vector:
std::vector<double> grade;
To insert a grade to the vector you can use grade.push_back(someGrade);

using pointers as private in class to access an array in c++

I am using a int pointer as private to access an array. When i write separate functions for store and get values to an array, the program crashes. But if i write the get value and store value code in constructor, the program works fine. I am not able to find where the problem is.
Program 1: (Which is not working)
#include<iostream>
using namespace std;
class NewArray{
private:
int Size = 0;
int *arrAddr = NULL;
public:
NewArray(int);
void SetValue(int);
void GetValueOf(int);
};
//Array is created
NewArray::NewArray(int arSz){
int arr[arSz];
Size = arSz;
arrAddr = arr;
cout << "An array of Size " << Size << " is created" << endl;
}
// Store Value function
void NewArray::SetValue(int index)
{
cin >> *(arrAddr+(index));
}
//Get value function
void NewArray::GetValueOf(int idx)
{
if ((idx >= Size) || (idx < 0))
{
cout << "index value is out of bound" << endl;
}
else
{
cout << *(arrAddr+idx) << endl;
}
}
int main()
{
int arrSize, arrIdx;
cout << "enter the size of array" << endl;
cin >> arrSize;
if (arrSize > 0)
{
NewArray ar(arrSize);
cout << "enter " << arrSize << " values. Enter the values one after the other." << endl;
for (int i = 0; i < arrSize; i++)
{
ar.SetValue(i);
ar.GetValueOf(i);
}
cout << "enter the index to fetch the value" << endl;
cin >> arrIdx;
ar.GetValueOf(arrIdx);
}
else{
cout << "invalid input" << endl;
}
return 0;
}
Program 2: (Code which is working)
#include<iostream>
using namespace std;
// size is passed
class NewArray{
private:
int Size;
int *arrAddr;
public:
NewArray(int);
void GetValueOf(int);
};
NewArray::NewArray(int arSz){
int arr[arSz];
int idx;
Size = arSz;
arrAddr = arr;
cout << "An array of Size " << Size << " is created" << endl;
// Storing values in array
cout << "enter " << Size << " values. Enter the values one after the other." << endl;
for (int i = 0; i < Size; i++)
{
cin >> *(arrAddr+i);
}
// To get the value from the index
cout << "enter the index to fetch the value" << endl;
cin >> idx;
if ((idx >= Size) || (idx < 0))
{
cout << "index value is out of bound" << endl;
}
else
{
cout << "The value is " << *(arrAddr+idx) << endl;
}
}
int main()
{
int arrSize, arrIdx;
cout << "enter the size of array" << endl;
cin >> arrSize;
if (arrSize > 0)
{
NewArray ar(arrSize);
}
else{
cout << "invalid input" << endl;
}
return 0;
}
I have tried for this particular example, program 1 crashes when the array size is 10 and when i am trying to write to 7th index.
Can anyone please help me find out why?
In the constructor NewArray::NewArray() you create an array, which is stored on the stack. After leaving the constructor its lifetime is over, it is removed from the stack, so accessing it through your pointer arrAddr is Undefined Behavior.
To simply fix the problem you need to allocate the array on the heap using new and delete or store it as a class member.
These are just two ways of implementing. I do not recommend anything, they are just possibilities.
int arr[arSz];
is allocated on stack and hence it's lifetime is limited to the function in which it is defined - the allocated stack memory is available for others once the stack is unwound. You need to allocate memory on heap using the new operator, for the memory to remain persistent after the function call.
arrAddr = new int[arSz];
The above allocates memory on heap and is available until explicitly deleted by a call to delete [] arrAddr, which in most cases should be done only in the destructor.
forgot about int *. use vector instead. look here
#include <iostream>
#include <conio.h>
#include <vector>
using namespace std;
class Class1 {
private:
vector<int> intArr;
public:
void Set(int iValue) {
intArr.push_back(iValue);
}
int Get(int iIndex) {
return intArr[iIndex];
}
};
int main() {
Class1 class1;
for (size_t i = 0; i < 10; i++)
{
class1.Set(i);
}
for (size_t i = 0; i < 10; i++)
{
cout << class1.Get(i) << endl;
}
_getch();
}

C++: Dynamically create array named after for loop iterator

Hey so I want to create n arrays (based off user input) of size x (also off user input). The way I was thinking of doing it was having a for loop perform n iterations and inside the loop ask the user for x. The problem is I'm not sure how to name the array using the variable n, I was thinking something like:
cout << "Enter n: ";
cin >> n
for (i = 0; i < n; i++)
{
cout << "Enter x: ";
cin >> x;
double*array+i;
array+i = new double[x]
}
To sum up my question is: can you create/name an array using a variable in C++?
Unfortunately, you can't do this in C++. Try something like this...
std::cout << "Enter n: ";
std::cin >> n
std::vector<std::vector<double> > arrays(n);
for (std::size_t i = 0; i < n; i++)
{
std::cout << "Enter x: ";
std::cin >> x;
arrays[i].reserve(x);
}
reserve only allocates, but does not construct the objects in the std::vector; if you want to construct them too, use resize.
PS Never use using namespace std; it makes your code harder to read and debug.
Since you are programming in C++, you should use STL containers (especially std::vector) instead of C-style arrays.
If you need to access an array by using the string that has been created in runtime, then you could use std::map< std::string, std::vector<double> >, which is pretty crazy idea though:
typedef std::vector<double> MyVector;
std::map<std::string, MyVector> myVectors;
// create an array:
std::string arrayName;
arrayName = std::string("someArray"); // could be: std::cin >> arrayName;
myVectors[arrayName] = MyVector(10, 1.23); // new vector of size 10
std::cout << myVectors["someArray"][4]; // prints 1.23
I'm not sure what exactly is what you are trying to achieve, but there are most likely more appropriate solutions. Is it really necessary to access these arrays via their names? I'm pretty sure that common std::vector< std::vector<double> > would suffice here.
Here's 3 solutions: the first is closest to your example code, the second is an improvement in order to be able to correctly retrieve the array elements within bounds, and the third is the reason why you are better served with vectors.
Solution 1:
It looks like you want your arrays to have names that are distinguishable by your loop iterator. Like Joe said, you could have an array of an array, so the inner arrays will be named array[0], array[1], ..., array[n - 1]. This will be achieved by using a pointer to pointer to double. Each of the inner pointers will be used to dynamically allocate arrays of double. Don't forget to delete the dynamically allocated memory.
#include <iostream>
int main()
{
unsigned int n;
std::cout << "Enter number of arrays: ";
std::cin >> n;
double** array = new double*[n];
for (int i = 0; i < n; ++i)
{
unsigned int size;
std::cout << "Enter size of array " << i << ": ";
std::cin >> size;
array[i] = new double[size];
for (int j = 0; j < size; ++j)
{
int element;
std::cout << "Enter element " << j << " of array " << i << ": ";
std::cin >> element;
array[i][j] = element;
}
}
for (int i = 0; i < n; ++i)
{
delete [] array[i];
}
delete[] array;
return 0;
}
Solution 2:
However, with the above code, you will have trouble accessing the elements of each inner array. Unless you memorized the size of each inner array you create with this, you might access something out of bounds. Therefore, an update to this code would be to add yet another array, let's call it sizeOfInnerArrays, where each of its element i keeps track of the size of inner array array[i]. Here's the update:
#include <iostream>
int main()
{
unsigned int n;
std::cout << "Enter number of arrays: ";
std::cin >> n;
double** array = new double*[n];
unsigned int* sizeOfInnerArrays = new unsigned int[n];
for (int i = 0; i < n; ++i)
{
std::cout << "Enter size of array " << i << ": ";
std::cin >> sizeOfInnerArrays[i];
array[i] = new double[sizeOfInnerArrays[i]];
for (int j = 0; j < sizeOfInnerArrays[i]; ++j)
{
int element;
std::cout << "Enter element " << j << " of array " << i << ": ";
std::cin >> element;
array[i][j] = element;
}
}
//prints out each array as curly-brace enclosed sets of doubles
for (int i = 0; i < n; ++i)
{
std::cout << "{";
for (int j = 0; j < sizeOfInnerArrays[i] - 1; ++j)
{
std::cout << array[i][j] << ", ";
}
std::cout << array[i][sizeOfInnerArrays[i] - 1] << "}" << std::endl;
}
// free dynamically allocated memory
for (int i = 0; i < n; ++i)
{
delete [] array[i];
}
delete[] array;
delete[] sizeOfInnerArrays;
return 0;
}
Solution 3:
However, that is too complicated, so you are better off using a container, like vector, as Joe suggested, whose data member keeps track of its size.
#include <iostream>
#include <vector>
int main()
{
unsigned int n;
std::cout << "Enter number of vectors: ";
std::cin >> n;
std::vector<std::vector<double> > myVec;
// ^ space between closing angle brackets not needed
// if using C++11 conforming compiler
for (int i = 0; i < n; ++i)
{
unsigned int size;
std::cout << "Enter size of vector " << i << ": ";
std::cin >> size;
std::vector<double> temp;
temp.reserve(size);
for (int j = 0; j < size; ++j)
{
double value;
std::cout << "Enter next value of vector " << i << ": ";
std::cin >> value;
temp.push_back(value);
}
myVec.push_back(temp);
}
for (int i = 0; i < myVec.size(); ++i)
{
std::cout << "{";
for (int j = 0; j < myVec.at(i).size() - 1; ++j)
{
std::cout << myVec.at(i).at(j) << ", ";
}
std::cout << myVec.at(i).back() << "}" << std::endl;
}
return 0;
}