Pointers for Member Functions - c++

I am currently trying to create a program to calculate the mass of a rocket with given time values by passing an array to a member function of a class. I want to use a pointer for the array. How do I go about doing that. Should the pointer be initialized in int main or the class. Any suggestions appreciated.
#include <cmath>
#include <cstring>
#include <fstream>
#include<iostream>
using namespace std;
class equip
{
public:
double mass[999999999], velocity, height, *time[999999999];
double calcmass(double* time);
double calcvelocity();
double calcheight();
double calctime();
private:
double T = 7000;
double g = 32.2;
double K = 0.008;
};
double equip::calcmass(double* time)
{
int i = 0;
for(i=0; i=999999999; i++)
{
return mass[i] = (3000 - 40 * time[i]) / g;
}
}
int main()
{
int i = 0;
equip rocket;
ifstream infile;
string filename;
cout<<"Enter input file name for time values: ";
cin>>filename;
infile.open(filename.c_str());
while(infile.fail())
{
cerr<<"Error opening file. \n";
cout<<"Enter file name: ";
cin>>filename;
infile.open(filename.c_str());
}
for(i=0; i<999999999; i++)
{
infile>>rocket.time[i];
}
for(i=0; i<999999999; i++)
{
cout<<rocket.mass[i];
}
return 0;
}

equip is a very large object. About 14 gigabytes in fact.
Automatic variables such as equip rocket are allocated on the execution stack. The default size of the execution stack on most desktop systems is about 1 to few megabytes.
A 14 gigabyte object will most definitely overflow a 1 megabyte stack.
Solution: Always use dynamic allocation for large arrays such as used here. Simplest solution is to use std::vector. Also, are you certain that you need the arrays to be that big?
for(i=0; i=999999999; i++)
This loop looks like it will never end because 999999999 is always true.
{
return ....
But in fact, the loop never repeats because the function immediately returns. Neither choice makes sense, although in combination their silliness sort of cancel each other out.

Change the size of array to a practical real number. If can't , go through Dynamic memory allocation.

Related

Array not working, but shows std::bad_alloc (How to fix this?)

just started studying c++ and i have to make a dynamic array with an function that gets the max array value and prints it. And there seems to be a problem with my code. What have i done wrong, please help (criticism is much appreciated):
#include <iostream>
using namespace std;
int getmax(int* arr,int n)
{
int res=arr[0];
for (int i=0;i<n;i++)
{
if (res<arr[i]) res=arr[i];
}
return res;
}
int main()
{
int*arr;
int n;
arr=new int[n];
cout<<"Enter array length: ";
cin>>n;
for(int i=0; i<n; i++)
{
cout<<"Enter array number "<<i+1<<". : ";
cin>>arr[i];
}
int maxi;
maxi=getmax(arr,n);
cout<<"Biggest number in array is "<<maxi;
delete[]arr;
return 0;
}
The comments already seem to have fixed your problem, but since you asked for (constructive) criticism, you should really study modern C++. In modern C++ we only use bare pointers when there is no other way. We also leverage the standard library whenever it is appropriate to do so. Just these two things will quickly make you a much more powerful programmer and reduce the opportunity for mistakes, provided you study the language and the library.
Here is an example of your program applying these principles:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
size_t n;
cout<<"Enter array length: ";
cin>>n;
vector<int> arr(n); // Create a vector with n integers
// Iterate over the vector
for( auto i = arr.begin(); i != arr.end(); ++i )
{
cout<<"Enter array number "<< (i-arr.begin())+1 << ". : ";
cin>>*i; // Assign the input to the vector element through the iterator
}
// Get an iterator pointing to the largest element in the vector
auto maxi = max_element(arr.cbegin(), arr.cend());
cout<<"Biggest number in array is "<< *maxi << '\n';
return 0;
}
The std::vector constructor allocates the memory, and the destructor frees the memory when arr goes out of scope. No more tedious matching new and delete. When you need to extend the lifetime of an object beyond the current scope use smart pointers or containers that have the lifetime your object needs.

c++ private array access and storing

i need to store number and sum it , but the compiler say the a.num[i] is inaccessible... Here my code
class number{
private:
int num[12];
public:
number(){
}
int totalnumber(){
int total =0;
for( int i=0 ; i<12 ; i++){
total= total + num[i];
}
return total;
}
};
int main(){
number a;
int a;
cout<<"Enter number :";
cin>>a.num[i];
while(a.num[i] < 0){
cout<<"You've entered invalid input."<<endl;
cout<<"Enter number :"<<endl;
cin>>a.num[i];
}
cout<<"Total amount saved is : RM"<<number.totalnumber()<<endl;
return 0;
}
I think the number constructor need to do something, but i cant figure it out:( . Is there any way i can store the array inside a private array as declare in class number?
There are a couple of problems with your code:
First you defined 2 variables with the same name in the "main" function:
number a;
int a;
Then you try to access the variable "i" in "cin>>a.num[i];" but "i" has not be declared yet assigned in the "main" function.
I guess and think what you may try to achieve with your code is to sum a couple of numbers that are entered by the user.
In this case you may want to to use "for" loop to iterate over "i" and store the numbers read into the array in your object of the "number" class.
To store the numbers, you may want to implement a method for your class, like this, because you can't access a member variable like "int num[12]" from the ouside when it is declared as a private member:
void storeNum(int num, int i){
num[i] = num;
}
Third, you create an object of the class "number" with the name "a", but in the last line of your code, you tried to access the method "totalnumber" but you did not specify the object to invoke the method on, instead to wrote the class name.
And then you forget to
#include <iostream>
which is required by the C++ standard if you want to access library functions, which are defined the in the "iostream" header file. Additionally, you may want to write
using namespace std;
at the top of your file to tell the compiler that you want to import all the identifiers from the std namespace into your current namespace; That is, you wan't to write "cout" instead to "std::cout".
( Edit: To make this clear: You should never never never write "using namespace std" in production code... Never. Unless you're learning the language and trying things out.. Then it's okay. Just to keep this in mind for later... )
For example, the finished code could look like this:
#include <iostream>
using namespace std;
class number{
private:
int num[12];
public:
number(){};
int totalnumber(){
int total =0;
for( int i=0 ; i<12 ; i++){
total= total + num[i];
}
return total;
}
void storeNum(int number, int i) {
num[i] = number;
}
};
int main(){
number a;
for(int i = 0; i < 12; i++) {
cout << "Enter Number:";
int num = 0;
cin >> num;
a.storeNum(num,i);
}
cout<<"Total amount saved is : RM"<< a.totalnumber()<<endl;
return 0;
}
Hopefully, I could resolve your problem I helped you to understand the C++ language a little bit better.
Edit:
I noticed you tried to handle invalid user input in your code. That was a good idea (I assume you know at least another language ;) ). But it's more important to get you syntax correct. You can worry about error handling later...

How does one dynamically resize arrays?

I'm trying to read an unknown number of elements into the array, when my size reaches the current capacity, I call a function to double the size and copy the contents of the old array into a new array. I got my '&' but it seems it's still passing the array by value.
#include <iostream>
#include <fstream>
using namespace std;
void resize(int*&, int&);
int main() {
ifstream in("numbers.input");
int cap = 10;
double avg;
int total = 0;
int size = 0;
int *arr = new int [cap];
int temp;
for(int i =0; i <cap; i++){
in >> temp;
if(size >= cap) {
resize(arr,cap);
}
arr[i]=temp;
total += arr[i];
size++;
}
avg = (double) total/cap;
cout << cap <<endl;
cout << size <<endl;
cout << total <<endl;
cout << avg;
return 0;
}
void resize(int *&arr,int &cap) {
cap*=2;
int* newArr = new int[cap];
for(int i = 0; i < cap; i++){
newArr[i] = arr[i];
}
delete [] arr;
arr = newArr;
}
Everything you try to implement 'by hand' is already in
the standard library. Use std::vector<> which implements
a doubling/reallocation strategy very similar to what you're
proposing.
#include <fstream>
#include <vector>
int main() {
std::ifstream in("numbers.input");
std::vector<int> arr;
int temp;
while (in >> temp) { arr.push_back(temp); }
// process your data ...
}
See http://www.cplusplus.com/reference/vector/vector/
To answer the question more literally: Arrays are always passed
by reference, typically by passing a pointer to the first element.
Your resize function is taking the pointer by reference and will modify the value of the variable it is called with. However you have a number of bugs:
You copy cap items out of the old array, but you have already doubled cap, leading to an out of bound access and a possible crash.
Your resize function never gets called, due to a bug in your input loop. You should step through in a debugger (or at least add some trace cout calls) to work out what is going on. Try to figure this one out, if you can't let me know.
Your average is using cap as the divisor, that is not correct.
Note: You should add in your question that you can't use vector, because that would be the normal way to do this.
Note 2: In your question, you should also say exactly what is going wrong with your program - "seems to be passing the array by value" is a bit vague - why do you think it isn't passing by value?

C++ Program Functions

I am having trouble with my functions. When I use a function to manipulate an array, and print it and move on to the next manipulation function, it uses the array that was previously manipulated instead of the original array. For example, when my function converts every negative number to a positive, I call the next function which zeros out all even numbers, and my array prints out all zeros, instead of using the array from the original.
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
#define NUMS_PER_LINE 10 // maximum numbers to be printed on each line.
int numbers[100]; // array to hold upto 100 integer numbers.
int numcnt; // actual count (<=100) of numbers in above array.
// reads file content into array
void read_array_from_file (const char filename[])
{
ifstream inpfile(filename);
if (!inpfile.is_open())
{
cout << "Can't open file : " << filename << endl;
exit(1);
}
numcnt=0; // Initialise count of read numbers
// Read numbers from the file into array.
inpfile >> numbers[numcnt];
while (!inpfile.eof()) // Read until EOF is reached.
{
numcnt++; // Got one more number from input file.
inpfile >> numbers[numcnt];
}
inpfile.close();
return;
}
// Print out all the values in the array
void print_array_content (int numsinaline)
{
int i;
for (i=0; i<numcnt+1; i++)
{
if ((i % numsinaline) == 0)
cout << endl;
cout << numbers[i] << " ";
}
cout << endl << endl;
return;
}
// calculate average
double calculate_average ()
{
int i;
float sum=0;
for (i=0; i<(numcnt-1); i++)
{
sum += numbers[i];
}
return (sum/(numcnt-1));
}
// Find numbers larger and smaller than the average.
void find_numbers_smaller_and_larger_than_average (int &larger, int &smaller, int average)
{
int i;
for (i=0; i<(numcnt-1); i++)
{
if (numbers[i] < average)
smaller++;
else if (numbers[i] > average)
larger++;
}
return;
}
// Convert negative numbers to positive in the array 'numbers'.
void convert_negative_to_positive ()
{
int i;
for (i=0; i<(numcnt-1); i++)
{
if (numbers[i] < 0)
numbers[i] *= -1;
}
return;
}
// Convert all even numbers into zero.
void zero ()
{
int i;
for (i=0; i<numcnt; i++)
{
if (numbers[i] > 0)
numbers[i] *= 0;
}
return;
}
First of all, you are using a global variable for your array, so you are never passing it to your function. When you change a global variable in the function, it changes the data in the array. You should be passing that data into the function and NOT using global variables.
Second, while(!inpFile.eof()) is bad! Don't do it.
For file streams:
std::vector<int> numbers;
std::ifstream fin("myfile");
std::copy(std::istream_iterator<int>(fin), std::istream_iterator(), std::back_inserter<vector<int> >(numbers));
Those 3 lines will read the entire file into the vector "numbers".
Third, when declaring your functions, pass the array:
void myFunction(const std::vector<int>& vec); // if you aren't going to change the vector
or
void myFunction(std::vector& vec); // if you are going to change it
and you would call it by simply:
myFunction(numbers);
" it uses the array that was previously manipulated instead of the original array."
Obviously because you have your array declared globally
int numbers[100];
Outside all functions.
When you perform one operation on this array, the element get modified and the new values will be used for next functions.
Instead of this, save of copy of your original array and then use this copy whenever you wish to work on original array
All your operations act on a single global variable, numbers. If you modify it in any of your functions its values will also change in every other occurrence.
Instead, provide a way to tell your functions which array you want to use, how many elements it contains and use several arrays. This also enables you to get rid of the global variable.
Example:
#include <iostream>
using namespace std;
typedef unsigned int array_size_t;
void print_array(int array[], array_size_t size){
for(array_size_t i = 0; i < size; ++i){
cout << array[i] << endl;
}
}
int main(){
int a1[] = {1,2,3,4};
int a2[] = {1,3,3,7,0,0,0,0};
print_array(a1,4);
print_array(a2,8);
}
Remark
If you're allowed use standard containers such as std::vector instead. The solution above is more C than C++-like.
You are using global variable. All your operation on numbers whatever index will change your certain position's value.
Another potential risk is if your input file contains more than 100 integers, you will do
inpfile >> numbers[100];
or some index number greater than 100.
which will cause a segmentation fault.
You should be very careful when using global variables
You are directly manipulating your array inside of your functions since it is defined globally, instead of passing in a copy as a parameter.
void modify(int[] array) {
//Modify copied array here
}
int main() {
int numbers[100];
int copyNumbers[100];
//Copy numbers
memcpy(copyNumbers, numbers, sizeof(numbers));
modify(copyNumbers);
//Use modified array
memcpy(copyNumbers, numbers, sizeof(numbers)); //Set back to original
modify(copyNumbers); //Modify copy again as original
}

Heap Corruption Detected: after Normal block (#126)

I cannot for the life of me figure out why I am getting this Debug Error:
Heap Corruption Detected: after Normal block (#126) at
0x004cF6c0
CRT detected that the application wrote to memory after end of heap bugger.
I understand that you need to free memory whenever you use new operator,
which I did and I am still getting problems.
for some reason the program doesn't end correctly in the recursive function.
I debugged it and went through each line of code with breakpoints.
At the end of the if statement in countSum it somehow subtracts 1 from i
and then reenters the if block.....which it is not supposed to do.
Why is this occurring?
/*this program calculates the sum of all the numbers in the array*/
#include <iostream>
#include <time.h>
using namespace std;
/*prototype*/
void countSum(int, int, int, int*);
int main(){
bool flag;
int num;
int sum = 0, j=0;
int *array = new int;
do{
system("cls");
cout<<"Enter a number into an array: ";
cin>>array[j];
cout<<"add another?(y/n):";
char choice;
cin>>choice;
choice == 'y' ? flag = true : flag = false;
j++;
}while(flag);
int size = j;
countSum(sum, 0, size, array);
//free memory
delete array;
array = 0;
return 0;
}
void countSum(int sum, int i, int size, int *array){
if (i < size){
system("cls");
cout<<"The sum is :"<<endl;
sum += array[i];
cout<<"...."<<sum;
time_t start_time, stop_time;
time(&start_time);
do
{
time(&stop_time); //pause for 5 seconds
}
while((stop_time - start_time) < 5);
countSum(sum, (i+1) , size, array); //call recursive function
}
}
array holds enough space for a single int:
int *array = new int;
but there is potentially an attempt to insert more than one int which would result in writing to memory that is not available. Either use a std::vector<int> or it must be known beforehand the maximum number of ints that will be entered before array is allocated.
If this is a learning exercise and you do not want to use std::vector<int> you could prompt the user to enter the number of ints they wish to enter:
std::cout << "Enter number of integers to be entered: ";
int size = 0;
std::cin >> size;
if (size > 0)
{
array = new int[size];
}
Then accept size number of ints. Use delete[] when you use new[].
The solution was to set the size new int[size]....although I wish that you didn't have to set a size if it is dynamic.