c++ dynamic array Floating Point exception - c++

For my homework I had to design an arraylist in c++ using only 1d arrays and pointers to make the array dynamic. I have done ample testing and my functions work correctly, but when I use the main that the teacher has provided me I get this floating point error. The point of this homework is to create a class that will work for the teachers main without changing any code in the main
here is the main:
#include "ArrayList.h"
#include <iostream>
using namespace std;
int main(int argc,char *argv[])
{
ArrayList arr;
for (int i=1;i<=50;i++)
{
arr.push_back(i);
}
cout << "Should contain numbers 1..50, is ";
cout << arr.toString() << endl;
for (int i=arr.size()-1;i>=1;i--)
{
arr.erase(arr[i]);
}
cout << "Should contain only 1, is ";
cout << arr.toString() << endl;
arr.erase(arr[0]);
for (int i=1;i<=50;i++)
{
if (i<=2)
arr.push_back(i);
else
{
int j=1;
while ((j<arr.size()) && (i%arr[j]!=0))
j++;
if (j==arr.size())
{
arr.push_back(i);
}
}
}
cout << "Prime numbers between 1 and 50 are: " << arr.toString() << endl;
}
here is my cpp:
#include<iostream>
#include<string>
#include<sstream>
#include "ArrayList.h"
using namespace std;
void ArrayList:: intialArr(int arr[])
{
for(int i = 0; i < length; i++)
{
arr[i] = 0;
}
}
string ArrayList:: toString()
{
std::ostringstream ss;
for(int i = 0; i < capacity; i++)
{
if(arr[i]>0 || arr[i] <0)
{
ss << arr[i] << " ";
}
}
return ss.str();
}
ArrayList::ArrayList()
{
length = 1;
capacity=0;
arr = new int[length];
intialArr(arr);
}
int& ArrayList:: operator[] (unsigned int i)
{
return arr[i];
}
void ArrayList:: push_back(int m)
{
if(capacity>=length)
{
int oldlength = length;
length = length*2;
int* curArr = new int[length];
intialArr(curArr);
for (int i = 0; i < oldlength; i++)
{
curArr[i] = arr[i];
}
delete [] arr;
arr = curArr;
}
arr[capacity] = m;
capacity++;
}
void ArrayList:: erase(int m)
{
if(capacity == length/2)
{
length = length/2;
int* curArr = new int[length];
intialArr(curArr);
for (int i = 0; i<capacity; i++)
{
curArr[i] = arr[i];
}
delete [] arr;
arr = curArr;
}
for(int i = 0; i < capacity; i++)
{
if(arr[i]==m)
{
for(int j = i; j<length; j++)
{
arr[j] = arr[j+1];
}
capacity--;
break;
}
}
cout << "length = " << length << " capacity = " << capacity << " capacity/length = " << capacity*2 << endl;
}
from what I have read online floating point exceptions are normally thrown when you try to divide by zero or an infinate value arises but I dont understand how I am getting either of these issues to arise.
My code get through the main where number 1-50 are added and deleted but I get the error once I go into setting up the array to hold prime numbers (after the arr.erase(arr[0]) in the main)
I just set a couple of tags in the main to find what my number look like going into the while ((j<arr.size()) && (i%arr[j]!=0))and i find that my numbers before the crash are
j = 1 and arr[j] = 2
i = 5 and arr.size() = 4

Related

Why is an array not returned from the addition operator?

The task is to create 2 variables of the Array class to populate them, output, add and multiply. I created 2 variables of the Array class, after which I wanted to add them, I wrote an addition operator for this, but it does not return an array of sums of the other two arrays
Code:
#include <iostream>
#include <fstream>
#include <string>
void showMenu() {
std::cout << "-------Menu-------" << std::endl <<
"1-Input matrix" << std::endl <<
"2-Print matrix" << std::endl <<
"3-Sum matrix" << std::endl <<
"4-Multiply matrix" << std::endl <<
"0-Exit" << std::endl <<
"------------------" << std::endl;
}
class Array {
public:
Array(const int size) {
this->size = size;
arr = new int[this->size];
}
void fillArr() {
std::cout << "Enter elements of array: ";
for (size_t i = 0; i < size; i++) {
std::cin >> arr[i];
}
}
int getSize() {
return size;
}
int& operator [] (const int index) {
return arr[index];
}
void showArr() {
for (size_t i = 0; i < size; i++) {
std::cout << arr[i] << '\t';
}
std::cout << std::endl;
}
~Array() {
delete[] arr;
}
private:
int size = 0;
int* arr;
};
Array operator + (Array arr1, Array arr2) {
int temp = 0;
if (arr1.getSize() < arr2.getSize())
temp = arr1.getSize();
else temp = arr2.getSize();
Array tempArr(temp);
for (size_t i = 0; i < temp; ++i) {
tempArr[i] = arr1[i] + arr2[i];
}
tempArr.showArr();
return tempArr;
}
Array operator * (Array arr1, Array arr2) {
int temp = 0;
if (arr1.getSize() < arr2.getSize())
temp = arr1.getSize();
else temp = arr2.getSize();
Array tempArr(temp);
for (size_t i = 0; i < temp; ++i) {
tempArr[i] = arr1[i] * arr2[i];
}
return tempArr;
}
std::int16_t main() {
int num = 0;
int size1 = 0, size2 = 0;
std::cout << "Enter size of first array: ";
std::cin >> size1;
std::cout << "Enter size of second array: ";
std::cin >> size2;
Array arr1(size1), arr2(size2);
while (true) {
showMenu();
std::cout << "Choice: ";
std::cin >> num;
switch (num) {
case 1:
arr1.fillArr();
arr2.fillArr();
break;
case 2:
arr1.showArr();
arr2.showArr();
break;
case 3: {
Array temp(arr1 + arr2);
temp.showArr();
break;
}
case 4:
(arr1 * arr2).showArr();
break;
}
}
}
I tried to change the array and the operator itself, but nothing came out. Help understand the problem
you need to read up on the rule of 3
here
Array tempArr(temp);
for (size_t i = 0; i < temp; ++i) {
tempArr[i] = arr1[i] + arr2[i];
}
tempArr.showArr();
return tempArr;
you return a copy of an Array instance. In that case both instances are pointing at the same newed array (arr). The first one to go out of scope (when you exit the operator + function) will delete that data, hence giving you garbage. Then when the second one is destroyed (at the break statement in the menu switch) it tries to delete the same array again., on my machine that errors out
https://en.cppreference.com/w/cpp/language/rule_of_three

How to delete the new array in c++?

I have created a new point function in c++, where I create a new array by Dynamic memory allocation. However, when I want to delete the array in main function, it reports errors like:
'Assessment_1.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\ucrtbased.dll'
'Assessment_1.exe' (Win32): Loaded 'C:\Windows\SysWOW64\ucrtbased.dll'.
The thread 0x22dc has exited with code 0 (0x0).
HEAP[Assessment_1.exe]: Invalid address specified to RtlValidateHeap( 00050000, 0005F25C )
Assessment_1.exe has triggered a breakpoint.
The return_array.cpp contains the function in which user inputs the keyboards.
#include<iostream>
#include <conio.h>
using namespace std;
//const static int length = 3;
int* input() {
//static int number[length]; fixed length for input
static int* number_array;
int number_length = 30;
int index = 0;
number_array = new int[number_length];
cout << "enter (ESC) to escape the program!" << endl;
while (_getch() != 27)
{
cout << "Input your number " << index << " elment: " << endl;
cin >> number_array[index];
index = index + 1;
cout << endl;
}
return number_array;
}
The practice.cpp contains the main function and the evaluation function of two vectors. The bug is when I add the delete []vector_1;.
#include <vector>
#include<iostream>
#include"myFunctions.h"
using namespace std;
const static int length = 3;
bool same_vec(vector<int> a, vector<int> b);
void main() {
vector<int> new_vector_1(length);
vector<int> new_vector_2(length);
int* vector_1 = input();
for (int i = 0; i < length; i++) {
new_vector_1[i] = *vector_1;
cout << *vector_1 << endl;
vector_1 = vector_1 + 1;
}
delete []vector_1;
for (int i = 0; i < length; i++) {
cout << " The result of vector_1: " << new_vector_1[i] << endl;
}
int* vector_2;
vector_2 = input();
for (int i = 0; i < length; i++) {
new_vector_2[i] = *vector_2;
vector_2 = vector_2 + 1;
}
delete []vector_2;
for (int i = 0; i < length; i++) {
cout << " The result of vector_2: " << new_vector_2[i] << endl;
}
bool qax = same_vec(new_vector_1, new_vector_2);
if (qax == false) {
cout << "the items are not match!"<<endl;
}
else {
cout << "the items are match!" << endl;
}
}
bool same_vec(vector<int> a, vector<int> b) {
//Evaluate the elements in the two vectors
bool flag = true;
int length_a = a.size();
int length_b = b.size();
vector<bool> new_bool(length_a);
for (int i = 0; i < length_a; i++) {
for (int j = 0; j < length_b; j++) {
if (a[i] == b[j]) {
new_bool[i] = true;
cout << a[i] << " " << b[j] << endl;
break;
}
}
}
for (int i = 0; i < new_bool.size(); i++) {
if (new_bool[i] == false) {
flag = false;
}
}
return flag;
}
And the myFunction.h is my head file.
#pragma once
int* getRandom();
int* input();
Can someone helps to solve the problem? I know one solution is delete the line of delete []vector_1;. The solution may cause memory-leak.
You are changing the address stored in the vector_1 pointer, then trying to delete[] something that no longer corresponds to the pointer returned by the new operator in your input function.
So, instead of this loop:
for (int i = 0; i < length; i++) {
new_vector_1[i] = *vector_1;
cout << *vector_1 << endl;
vector_1 = vector_1 + 1; // This line changes the pointer!
}
delete []vector_1; // And, here, the pointer is NOT what "new" gave you!
Use something like this, instead:
for (int i = 0; i < length; i++) {
new_vector_1[i] = vector_1[i]; // You can use the [] operator on the pointer
cout << *vector_1 << endl;
// vector_1 = vector_1 + 1; // Remove this line, as it's causing the problem!
}
delete []vector_1;
Also, you have exactly the same problem in the loop that deals with the vector_2 pointer - and the same 'fix' will work there, too.
Note: If you don't want to use the [i] index operator, but rather use pointer 'arithmetic', then you can change:
new_vector_1[i] = vector_1[i];
to:
new_vector_1[i] = *(vector_1 + i);
This way, you are adding the value of i to the pointer without changing that pointer.

Program is meant to count how many duplicates are in an array. However, it returns the wrong frequency values

Normally I would use other methods to fix this program but I am not allowed to use advanced techniques for this project, and so what I have is more or less as far as I'm allowed to go.
So my program is meant to take in an array with 10 numbers and then output how many of each value is in the array. For example, {1, 1, 1, 1, 1, 2, 2, 2, 2, 2} is meant to return
5 1
5 2
However, it returns
6 1
4 2
I've made sure that the finalData and Data arrays are holding the proper values.
cout << count(data, data + MAX_VALUE, finalData[i+1]) << " " << data[i] << "\n";
seems to be outputting the wrong value.
for some reason. I believe the error is in my last function, getResults, more specifically the last for loop. Here is that function.
void getResults(int finalData[], int data[])
{
int temp[MAX_VALUE];
int j = 0;
for (int i = 0; i < MAX_VALUE - 1; i++)
if (finalData[i] != finalData[i + 1])
temp[j++] = finalData[i];
temp[j++] = finalData[MAX_VALUE - 1];
for (int i = 0; i < j; i++)
{
finalData[i] = temp[i];
}
for (int i = 0; i < j; i++)
{
cout << count(data, data + MAX_VALUE, finalData[i+1]) << " " << data[i] << "\n";
}
}
This is my complete code.
#include<iostream>
#include<iomanip>
#include<string>
#include<cmath>
#include <algorithm>
using namespace std;
void printHeader();
int getData(string);
void getResults(int finalData[], int data[]);
const int MAX_VALUE = 10;
int main(void)
{
int countValue = 0;
int freq = 0;
printHeader();
int data[MAX_VALUE] = {};
int frequency[MAX_VALUE] = {};
for (int i = 0; i < MAX_VALUE; i++)
{
cout << "Please enter data position " << i + 1 << "\n";
data[i] = getData("\nPlease enter a valid integer.\n");
}
sort(data, data + MAX_VALUE);
int values[MAX_VALUE] = {};
int secondData[MAX_VALUE] = {};
for (int i = 0; i < MAX_VALUE; i++)
{
secondData[i] = data[i];
}
getResults(data, secondData);
return 0;
}
void printHeader()
{
}
int getData(string error)
{
int userInput = 0;
do
{
cin >> userInput;
if (cin.fail())
{
cout << error;
}
} while (cin.fail());
return userInput;
}
void getResults(int finalData[], int data[])
{
int temp[MAX_VALUE];
int j = 0;
for (int i = 0; i < MAX_VALUE - 1; i++)
if (finalData[i] != finalData[i + 1])
temp[j++] = finalData[i];
temp[j++] = finalData[MAX_VALUE - 1];
for (int i = 0; i < j; i++)
{
finalData[i] = temp[i];
}
for (int i = 0; i < j; i++)
{
cout << count(data, data + MAX_VALUE, finalData[i+1]) << " " << data[i] << "\n";
}
}
Got the right answer. Made the changes I listed at the top as well as the following change to the count function.
cout << count(data, data + MAX_VALUE, finalData[i]) << " " << finalData[i] << "\n";
You have done a simple error. When you call getResults you pass the same array(pointer) to 2 different parameters. Now when you update finalData the unwanted side effect update also data(they are the same pointer(with different name). So when you call count will not return the expected result.
To solve this problem you can do a copy of the input array and give it as second parameter of getResults(...) function.

Square Root Code C++ without sqrt()

I have to create a code where the user inputs a number which is a perfect square, and I have to show its root. I've made this code, but I'm getting Segmentation Fault 11 , in this piece: int j = squareRootVector[i];
squareRoot.push_back(j);.
I can't change the code too much, so is there a way that I can do that?
#include <iostream>
#include <vector>
using namespace std;
int main() {
cout <<
"Enter the number:\n";
int input;
int number = input;
int divider = 2;
vector<int> squareRootVector;
vector<int> squareRoot;
cin >> number;
for(int divider = 2; number > 1; divider++) {
while((number % divider) == 0) {
number /= divider;
cout << number << endl;
squareRootVector.push_back(divider);
}
}
for(int i = 0; i < squareRootVector.size(); i++) {
cout << squareRootVector[i] << " ";
/*******PROBLEM*******/
if(squareRootVector[i] == squareRootVector[i+1]) {
int j = squareRootVector[i];
squareRoot.push_back(j);
}
/*********************/
}
int root;
for (int i = 0; squareRoot.size(); i++) {
root = root * squareRoot[i];
}
cout << "Square Root of " << input << " is: " << root << endl;
return 0;
}
The behaviour on accessing squareRootVector[i+1] with i just one below size (which your loop constaint allows) is undefined.
Consider writing
for (std::size_t i = 1; i < squareRootVector.size(); i++) {
instead, and rebasing the for loop body accordingly. I've also slipped in a change of type for i.
Shortly, the problem is that the last cycle in the last "for":
for(int i = 0; i < squareRootVector.size(); i++)
has the following line in it:
squareRootVector[i] == squareRootVector[i+1];
This is an "out of limits" error: squareRootVector only has squareRootVector.size() elements (let's say n), and the elements are indexed from 0 to n-1.
squareRootVector[i+1] in the last cycle points one element after the last one of squareRootVector, which is undefined behavior.
Using vector::iterator is proper way.
for(vector<int>::iterator it = squareRootVector.begin(); it != squareRootVector.end(); ++it)
{
if( (it+1) == squareRootVector.end() )
{
//what to do if there's no next member???
break;
}
if( *it == *(it+1) )
{
squareRoot.push_back(*it);
}
}
Thanks for the answers, guys. I've ended up with this code:
#include <iostream>
#include <vector>
using namespace std;
int main() {
cout << "Enter the number:\n";
int input = 0;
int number = 0;
cin >> input;
number = input;
int divider = 2;
vector<int> squareRootVector;
vector<int> squareRoot;
for(int divider = 2; number > 1; divider++) {
while((number % divider) == 0) {
number /= divider;
squareRootVector.push_back(divider);
}
}
int vectorSize = squareRootVector.size() - 1;
for(int i = 0; i < vectorSize; i++) {
if(squareRootVector[i] == squareRootVector[i+1]) {
int j = squareRootVector[i];
squareRoot.push_back(j);
}
}
int root = 1;
for (int i = 0; i < squareRoot.size(); i++) {
root = root * squareRoot[i];
}
cout << "Square Root of " << input << " is " << root << endl;
return 0;
}

Odd results after first float entered

I have created a program to take in float values until a non-number is entered. The program will then print the numbers entered like {n0,n1,...,}, as well as sum up the number entered and compute the average.
My problem is after n0 is printed out all the rest of the numbers being printed out are not matching the number entered.
Here is the program:
#include <iostream>
using namespace std;
class ManagedArray
{
float *elements;
int numberOfElements;
public:
ManagedArray(float *ele, int NOE)
: elements(ele), numberOfElements(NOE)
{}
ManagedArray()
{
elements = NULL, numberOfElements = 0; //default constructor
}
int Size();
float get(int index);
void add(float value);
~ManagedArray(); // Destructor
ManagedArray(ManagedArray & ma); // copy constructor
void print(ManagedArray ma);
};
float ManagedArray::get(int index) { return elements[index]; }
int ManagedArray::Size() { return numberOfElements; };
void ManagedArray::add(float value)
{
float * biggerArray = new float[numberOfElements + 1];
if (elements != NULL)
{
// copy the old elements into the biggerArray
for (int i = 0; i < numberOfElements; i++)
{
biggerArray[i] = elements[i];
}
// the old array is not needed anymore, we have a better copy
delete[] elements;
}
// point at the new array
elements = biggerArray;
numberOfElements = numberOfElements + 1;
// put the new number into the last element of the array
elements[numberOfElements - 1] = value;
}
ManagedArray::~ManagedArray() { delete[] elements; }
ManagedArray::ManagedArray(ManagedArray & ma)
{
elements = new float[10]; // put here to get the number of input here
for (int i = 0; i <10; i++) // put here to get the number of input here
{
elements[i] = ma.elements[i];
}
numberOfElements = ma.numberOfElements;
}
void ManagedArray::print(ManagedArray ma)
{
bool hasNumbers = ma.Size() > 0;
if (hasNumbers) {
// print the stored numbers
cout << "Entered numbers: " << endl;
cout << "{";
for (int i = 0; i < ma.Size(); ++i)
{
if (i > 0)
{
cout << ", ";
}
cout << ma.get(i);
}
cout << "}" << endl;
float sum = 0;
for (int i = 0; i < ma.Size(); ++i)
{
sum += ma.get(i);
}
cout << "total: " << sum << endl;
cout << "average: " << (sum / ma.Size()) << endl;
}
else {
cout << "no numbers entered." << endl;
}
}
int main()
{
ManagedArray mArray; // default constructor call for ManagedArray
float userInput;
bool addingNumbersToTheList;
cout << "Keep entering numbers. Enter a non-number to stop." << endl;
do
{
cin >> userInput;
addingNumbersToTheList = !std::cin.fail();
if (addingNumbersToTheList) {
mArray.add(userInput);
}
} while (addingNumbersToTheList);
ManagedArray copy(mArray);
// fix cin after intentionally breaking it above.
if (std::cin.fail())
{
std::cin.clear();
while (std::cin.get() != '\n');
}
copy.print(copy);
copy.print(copy);
cin.get();
return 0;
}
So for instance I enter 1 , 2 , 3 , a
the program would print out {1, -4.22017e+37, 2.89451e+31}
Could someone point out what I am doing wrong with this method?
EDIT: I have fixed the copy constructor. Can someone show me how I would replace
the number 10 with the total of numbers input? in:
elements = new float[10];
and
for (int i = 0; i <10; i++)
I needed to iterate through every possible number in the array with a for loop and an array.
elements = new float[ma.Size()];
for (int i = 0; i < ma.Size(); i++)
{
elements[i] = ma.elements[i];
}
numberOfElements = ma.numberOfElements;