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();
}
Related
I just need to know how to have size, index, and counter keep their values when they are called in another function. Right now they are just being given random values when they are called instead of the values I'm initializing them with in the constructor. How can I fix this? The objective for this code is to make a program that Captures a string of words from a user of the program (via the keyboard) and adds the entered
words to a dynamic array of strings.
This is the array.cpp file
#include "array.h"
using namespace std;
Array::Array()
{
int size = 100;
int index = 0;
int counter = 0;
counter ++;
index++;
string *ptr = new string[size];
}
Array::~Array()
{
delete ptr;
ptr = nullptr;
}
void Array::populate()
{
string word;
cout << "Enter word to add to array: ";
cin >> word;
ptr[index] = word;
}
void Array::printContent()
{
cout << "Number of words in array: " << counter << endl;
cout << "Array size: " << size << endl;
cout << "Words in array: " << endl;
for (int i = 0; i < counter; i++)
{
cout << ptr[i] << endl;
}
}
void Array::displayMenu() const
{
cout << "[1] Add Word\n"
<< "[2] Print Array Information\n"
<< "[3] Quit Program\n"
<< "Enter Choice: ";
}
int Array::getChoice(int & choice1)
{
cin >> choice1;
while (choice1 < 1 || choice1 > 3) {
cout << endl;
cout << "Invalid Entry!!" << endl;
cout << "Enter Choice: ";
cin >> choice1;
}
return choice1;
}
int Array::endProgram(int & start2)
{
start2 = 0;
cout << "\n\n\t\tThank you for using this system!!\n\n";
return start2;
}
This is the array.h file
#include <iostream>
#include <string>
using namespace std;
class Array {
public:
Array();
~Array();
void populate();
void printContent();
void displayMenu() const;
int getChoice(int & choice1);
int endProgram(int & start2);
private:
int size;
int index;
int counter;
string *ptr;
};
Lastly this is the main.cpp file
#include <iostream>
#include "array.h"
using namespace std;
int main() {
int choice = 0;
int start = 1;
Array theArray;
while(choice != 3)
{
theArray.displayMenu();
theArray.getChoice(choice);
if(choice == 1)
{
theArray.populate();
}
if(choice == 2)
{
theArray.printContent();
}
if (choice == 3)
{
theArray.endProgram(start);
}
}
}
You are defining new local variables inside of your Array constructor and shadowing the member variables of the same name -- which is why the value isn't being preserved.
You only need to specify the type when defining new variables, but not when assigning to existing ones. To assign to the member variables, this should be:
Array::Array()
{
size = 100;
index = 0;
counter = 0;
ptr = new string[size];
...
}
Additionally, in constructors its more correct to use constructor initializer lists to initialize the values:
Array::Array()
: size{100},
index{0},
counter{0},
ptr{new string[size]}
{
...
}
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;
}
I have this code of a dynamic array that I turned in as a lab. My instructor responded saying "wouldn't even compile, no resize of the array". I am having trouble dealing with the comment of "no resize of the array", meaning I have to add the ability to resize the array. Please help quick! (It does compile). Appreciate it.
I am supposed to make a program that asks the user to initially size the array. Create an array based on that size asking for a number, and insert the number. Then repeat getting and inserting a number, resizing the array as needed or until they enter -1 for the number.
Print the list.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int count;
cout << "How many values do you want to store in your array?" << endl;
cin >> count;
int* DynamicArray;
DynamicArray = new int[count];
for (int i = 0; i < count; i++) {
cout << "Please input Values: " << endl;
cin >> DynamicArray[i];
{
if (DynamicArray[i] == -1) {
delete[] DynamicArray;
cout << "The program has ended" << endl;
exit(0);
}
else {
cout << endl;
}
}
}
for (int k = 0; k < count; k++) {
cout << DynamicArray[k] << endl;
}
delete[] DynamicArray;
return 0;
}
When the array is full, we need to resize it. Here is my solution
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
int main()
{
int count;
cout << "How many values do you want to store in your array?" << endl;
cin >> count;
if (count <= 0) {
cout << "The value should be greater than zero" << endl;
exit(0);
}
int* DynamicArray;
DynamicArray = new int[count];
int i = 0, value = 0;
while (1) {
cout << "Please input Values: " << endl;
cin >> value;
if (value == -1) {
cout << "The program has ended" << endl;
break;
}
else if (i < count)
{
DynamicArray[i++] = value;
}
else
{
// resize the array with double the old one
count = count * 2;
int *newArray = new int[count];
memcpy(newArray, DynamicArray, count * sizeof(int));
delete[]DynamicArray;
newArray[i++] = value;
DynamicArray = newArray;
}
}
for (int k = 0; k < i; k++) {
cout << DynamicArray[k] << endl;
}
delete[] DynamicArray;
return 0;
}
In visual studio program crashes: error debug assertion failed. What is wrong in my code? There is no syntax errors. Only warning: deletion of array expression,conversion to pointer suplied When i run it with cmd standart compiler it works fine.
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
using namespace std;
#define max_size 100
class my_array{
int* arr[max_size];
public:
my_array() {}
my_array(int size) {
if (size <= 0 || size > max_size) {
exit(1);
}
for (int i = 0; i < size; i++) {
arr[i] = new int;
cout << "Enter element [" << i + 1 << "] = ";
cin >> *arr[i];
}
}
~my_array() {
delete[] arr;
}
void operator[](int n) {
cout << endl;
for (int i = 0; i < n; i++) {
cout << "Enter element [" << i << "] = " << *arr[i] << endl;
}
}
};
int main() {
my_array array(6);
array[5];
return 0;
}
You are deleting arr here:
delete[] arr;
while arr has never been allocated by new. In your original program arr is a fixed size array of pointers to int.
You probably want this:
class my_array {
int *arr;
public:
my_array() {}
my_array(int size) {
if (size <= 0 || size > max_size) { // BTW this test isn't really necessary, as we
// can allocate as much memory as available
// anyway much more than just 100
exit(1);
}
arr = new int[size]; // allocate array of size size
for (int i = 0; i < size; i++) {
cout << "Enter element [" << i + 1 << "] = ";
cin >> arr[i];
}
}
~my_array() {
delete[] arr; // delete array allocated previously
}
void operator[](int n) {
cout << endl;
for (int i = 0; i < n; i++) {
cout << "Enter element [" << i << "] = " << arr[i] << endl;
}
}
};
Instead of having a fixed size array of pointers to int, you have a dynamic array of ints.
There is still room for improvement though. For example the my_array() constructor is pointless here, And it's odd to use the [] operator for printing the content, and the text "Enter element [" in the [] operator is also questionable.
I am having trouble returning my two arrays that I dynamically allocate. I have an external file reading the size of the array. (20 in my case) and that is making the array size when I use the dynamically allocated arrays.
Also once I return them, is my current syntax correct or is there something that I should change.
Here is my code
int main (void)
{
int size;
int notFound = 0;
int accountNumber = 0;
int results;
int * accountPtr = nullptr;
double * balancePtr = nullptr;
size = readFile(notFound, accountPtr, balancePtr);
if (notFound == 0)
{
selectionSort(accountPtr, balancePtr, size);
while (accountNumber != -99)
{
cout << "Please Enter an Account Number (Type -99 to quit): ";
cin >> accountNumber;
if (accountNumber == -99)
{
cout << "Goodbye!" << endl;
}
else
{
results = binarySearch(accountPtr,accountNumber,size);
if ( results == -1)
{
cout << "That Account Number Does Not Exist." << endl;
}
else
{
cout << "\nAccount Number" << "\t\t" << "Account Balance" << endl;
cout << "-----------------------------------------------" << endl;
cout << fixed << setprecision(2) << accountPtr[results] << "\t\t\t" << balancePtr[results] << endl << endl;
}
}
}
}
return 0;
}
int readFile (int ¬Found, int *accountPtr, double *balancePtr)
{
int size;
ifstream inputFile;
inputFile.open("account.txt");
if (inputFile.fail())
{
cout << "The File Account.TXT was not found." << endl;
notFound = 1;
}
else
{
inputFile >> size;
unique_ptr<int[]> accountPtr(new int[size]);
unique_ptr<double[]> balancePtr(new double[size]);
for(int i = 0; i < size; i++)
{
inputFile >> accountPtr[i] >> balancePtr[i];
}
}
return size;
}
You're passing pointers by value. The pointer variables in the calling code will not be modified. In addition to passing by value, in the function you're declaring local variables of the same names as the formal arguments.
Instead you should be returning or passing by reference std::vector.