The purpose of this program is for the user to declare the size of their array, then have various functions operate on it. My problem is I realize nothing valid is declared in FunctionTwo. How can I get information from my main function to FunctionTwo and so on for my other functions as well?
int main()
{
srand(time(NULL));
int arraySize = 0;
cout << "How large would you like your array to be?" << endl;
cin >> arraySize;
int theArray [arraySize];
int selection = 0;
cout << "What would you like to do with your array? " << endl << endl;
cout << "1. Pass in an integer location and return the value. " << endl;
cout << "2. Initialize an array of all 0's. " << endl;
cout << "3. Initialize an array of random numbers between 1 and your specification. " << endl;
cout << "4. Populate an array one at a time. " << endl;
cout << "5. Select a position in the array and set that value to your specification. " << endl;
cout << "6. Print the entire array. " << endl;
cout << "7. Find the average of each value in the array. " << endl;
cout << "8. Find the largest element of the array. " << endl;
cout << "9. Find the smallest element of the array. " << endl;
cout << "12. Print all numbers in the array larger than your input. " << endl;
cout << "13. Tell if the array is empty. " << endl;
cout << "15. Return the difference between the largest and smallest value in the array. " << endl;
cin >> selection;
}
int FunctionTwo()
{
int theArray [arraySize] = {0};
return theArray;
}
int theArray [arraySize]; is not valid C++ if arraySize is only known at run-time.
The correct solution for your problem in C++:
std::vector<int> theArray(arraySize);
In C++ the size of an array shall be a constant expression known at compile time. This code
int arraySize = 0;
cout << "How large would you like your array to be?" << endl;
cin >> arraySize;
int theArray [arraySize];
is not C++ compliant because variable arraySize is not a constant expression.
So either you will set a fixed size of the array yourself without asking the user to specify the size as for example
const int arraySize = 20;
int theArray [arraySize];
or you must to allocate dynamically the array as for example
int arraySize = 0;
cout << "How large would you like your array to be?" << endl;
cin >> arraySize;
int *theArray = new int[arraySize];
In this case do not forget to delete the array before exiting the program:
delete []theArray;
You could use standard container std::vector<int> but I am sure that your assignment requires to use an array.
As for the function call of FunctionTwo then the function has to have two parameters: pointer to the first element of the array and the number of elements in the array. There is no sense to declare its return type as int, It would be better to declare it as void Here an example
void FunctionTwo( int theArray[], int arraySize )
{
for ( int i = 0; i < arraySize; i++ ) theArray[i] = 0;
}
Or you may use standard algorithm std::fill. For example
#include <algorithm>
//...
void FunctionTwo( int theArray[], int arraySize )
{
std::fill( theArray, theArray + arraySize, 0 );
}
Here is an example of so-called FunctionThree that has to initialize the array with random numbers in the range [1, n]
void FunctionThree( int theArray[], int arraySize, int n )
{
for ( int i = 0; i < arraySize; i++ ) theArray[i] = std::rand() % n + 1;
}
Or the same but using standard algorithm std:::generate
#include <algorithm>
//...
void FunctionThree( int theArray[], int arraySize, int n )
{
std::generate( theArray, theArray + arraySize, [&] { return ( std::rand() % n + 1 ); } );
}
Take into account that functions shall be declared before their usage.
As for the menu that it should be enclosed in a loop. For example
do
{
cout << "What would you like to do with your array? " << endl << endl;
cout << "1. Pass in an integer location and return the value. " << endl;
cout << "2. Initialize an array of all 0's. " << endl;
cout << "3. Initialize an array of random numbers between 1 and your specification. " << endl;
cout << "4. Populate an array one at a time. " << endl;
cout << "5. Select a position in the array and set that value to your specification. " << endl;
cout << "6. Print the entire array. " << endl;
cout << "7. Find the average of each value in the array. " << endl;
cout << "8. Find the largest element of the array. " << endl;
cout << "9. Find the smallest element of the array. " << endl;
cout << "12. Print all numbers in the array larger than your input. " << endl;
cout << "13. Tell if the array is empty. " << endl;
cout << "15. Return the difference between the largest and smallest value in the array. " << endl;
cout << "\n0. Exit from the program" << endl;
cin >> selection;
//...some other code
} while ( selection != 0 );
How can I get information from my main function to FunctionTwo and so on for my other functions as well?
You can provide function arguments. For example:
int FunctionTwo(std::vector<int>& the_vector)
Then in main():
switch (selection)
{
case 2: FunctionTwo(the_vector); break;
...other cases...
}
int FunctionTwo(int[] theArray) {}
This would allow you to use theArray inside the function. Hopefully this is what you meant. I was somewhat unclear on exactly what you wanted to do.
Now you can call the function as so:
FunctionTwo(anArray);
Related
This question already has answers here:
invalid conversion from 'int' to 'int*' [-fpermissive] on passing array
(3 answers)
Closed 4 years ago.
void drawTable(int arg[], int length);
int main()
{
int length=0;
int counter=0;
int *pointer2ArrSize = new int[length];
cout << "Enter length of array: " << endl;
cin >> length;
do{
for(int j=0; j<length; j++){
cout << "Enter array elements: \n";
cin >> pointer2ArrSize[j];
cout << "You entered: " << pointer2ArrSize[j] << " in position: "
<< j+1
<< endl;
counter++;
}
cout << drawTable(pointer2ArrSize[j],length) << endl;
}while(!counter == length);
return 0;
}
void drawTable(int arg[], int length){
for(int i=0; i<length; i++){
cout << arg[i] << " ";
cout << '/n';
}
}
error: invalid conversion from 'int' to 'int*' [-fpermissive]
My goal is to display a 2D variable length array. I want the user to define the length of the array and the elements in it. However, am not too familiar with vectors yet. how could I approach this?
cout << drawTable(pointer2ArrSize[j],length) << endl;
is wrong since the argument type for drawTable is int* and you are passing pointer2ArrSize[j] to it, which is of type int.
You need to use
cout << drawTable(pointer2ArrSize, length) << endl;
More importantly, use of
int *pointer2ArrSize = new int[length];
cout << "Enter length of array: " << endl;
cin >> length;
is wrong.
The array will not be resized to length after you accept its value from the user. Consequently, pointer2ArrSize will continue to be an array of size 0. Since pointer2ArrSize continues to be an array of size 0, any attempt to access its elements will result in undefined behavior.
Move the line that allocates memory after you have accepted the input value for length.
cout << "Enter length of array: " << endl;
cin >> length;
int *pointer2ArrSize = new int[length];
It will be better still to use std::vector. Then, you don't have to worry about memory allocation and deallocation.
cout << "Enter length of array: " << endl;
cin >> length;
std::vector<int> pointer2ArrSize(length);
Of course, you should change drawTable to accept a std::vector<int>.
void drawTable(std::vector<int> const& arg);
There won't be the need for length as a second argument to drawTable since you can get the size of the array from the std::vector.
I am failing to reach expected output when testing my 'grow'and 'subArray' functions. I've tried dereferencing back and forth in the function and also in main(). I'm wondering if there's something wrong with my memory allocation that is causing the lapse. I am extremely stuck and was hoping someone could potentially see something that I am missing, thanks.
#include <iostream>
#include <iomanip>
using namespace std;
bool isSorted(int *arr, int size){
for(int index = 0; index < size - 1; index ++){
if(*(arr + index) > *(arr + index + 1)){
return false;
}
}
return true;
}
double chain (int totalInches, int *feet, int *inches){
*feet = totalInches/12;
*inches = totalInches%12;
return *(feet)*3.49 + *(inches)*.30;
}
int *grow (int *arr, int size){
int *newArray;
newArray = new int[size*2]; //alocate new array
for(int i = 0; i < size*2; i+=2){
*(newArray + i) = *(arr+i);
*(newArray + i + 1) = *(arr+i);
}
return newArray;
}
int *duplicateArray (int *array, int size) {
int *newArray;
if (size <= 0)
return NULL;
newArray = new int [size]; //allocate new array
for (int index = 0; index < size; index++){
newArray[index] = array[index]; //copy to new array
}
return newArray;
}
int *subArray( int *array, int start, int length){
int *result = duplicateArray(array,5);
return result;
}
void showArray( int *arr, int size){
for(int i = 0; i < size; i ++)
{
cout << *(arr + i) << " ";
}
}
int main(){
int size = 8;
int testArray[] = {1,2,3,4,5,6,7,8};
cout << "testing isSorted: " << endl;
cout << "test data array 1: ";
showArray(testArray, size);
cout << endl;
cout << "Expected result: true" << endl;
cout << "Actual result: " << boolalpha << isSorted(testArray, size);
cout << endl;
int testArray2[]= {8,7,6,5,4,3,2,1};
cout << "test data array 2: ";
showArray(testArray2, size);
cout << endl;
cout << "Expected result: false" << endl;
cout << "Actual result: " << boolalpha << isSorted(testArray2, size);
cout << endl << endl << endl;
int chainTest = 53;
cout << "Checking chain for 53 inches: " << endl;
cout << "Expected result: 15.46 " << " " << "feet: 4 " <<
" " << "inches: 5"<< endl;
int in;
int ft;
cout << "Actual results : " << chain(chainTest,&ft,&in);
cout << " " << "feet: " << ft << " " << "inches: " << in << endl;
cout << endl << endl;
cout << "testing grow: " << endl;
cout << "test data 1: ";
showArray(testArray, size);
cout << endl;
cout << "Expected result: 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 " << endl;
cout << "Actual results: " << *(grow(testArray, size));
cout << endl << endl;
cout << "testing subArray:" << endl;
cout << "test data: ";
showArray(testArray, size);
cout << endl;
int start = 5;
int length = 3;
cout << "start: " << start << " " << "length: " << length << endl;
cout << "Expected result: " << "6 7 8" << endl;
cout << "Actual result: " << *(subArray(testArray, start, length));
cout << endl;
return 0;
}
Output:
As you notice, the loop is terminating after one traversal. The grow function is intended to duplicate and expand. In other words, it's supposed to make a copy of itself and append as it traverses. Any ideas as to why I am getting hung on the first element of the array?
You are actually doubling the array but only the first element is being printed because you are dereferencing an int* . To print all the elements, write a loop and print all the elements.
Also there is so much memory leak here. Please free memory after you are done using it. You are read about the delete[] operator.
Your loop going two at a time is good but it prevents you from selecting every element in the original array causing you to skip the even numbers. check your for loop and consider using two counters or if you want to modify your for loop to
for(int i = 0; i < size*2; i+=2){
*(newArray + i) = *(arr+i/2);
*(newArray + i + 1) = *(arr+i/2);
}
to ensure every element is reached
also as stated in the comments, use the showArray method you implemented
showArray(grow(testArray, size),size*2);
I created a random, and its size is created randomly. Then I assign random values to this array. Finally, I want to write odd values and even values into different arrays. But the last two for loops display wrong values for evenArray and oddArray.
Where is the error? Please help me identify the error.
#include <iostream>
#include <time.h>
#include <stdlib.h>
using namespace std;
int main()
{
srand(time(0));
int arraySize = rand() % 10 + 4;
cout << "Array Size : " << arraySize << endl;
int myArray[arraySize];
int oddIndex = 0;
int evenIndex = 0;
int oddArray[oddIndex];
int evenArray[evenIndex];
for( int m = 0 ; m < arraySize ; m++)
{
myArray[m] = rand() % 100 + 90 ;
cout << m << "th value is : " << myArray[m] << endl;
}
for( int i = 0; i < arraySize ; i++)
{
if( myArray[i] % 2 == 0)
{
evenArray[evenIndex] = myArray[i];
cout << "EVEN ARRAY " << evenIndex << "th element is " << evenArray[evenIndex] << endl;
evenIndex++;
}
else
{
oddArray[oddIndex] = myArray[i];
cout << "ODD ARRAY " << oddIndex << "th element is " << oddArray[oddIndex] << endl;
oddIndex++;
}
}
cout << "The total number of even array elements : " << evenIndex << endl;
cout << "The total number of odd array elements : " << oddIndex << endl;
cout << "/////////////////////////////////////////\n";
cout << "EVEN VALUES" << endl;
for( int i = 0 ; i < evenIndex ; i++ )
{
cout << i << "th even value is: " << evenArray[i] << endl;
}
cout << "/////////////////////////////////////////\n";
cout << "ODD VALUES" << endl;
for( int p = 0 ; p < oddIndex ; p++ )
{
cout << p << "th odd value is : " << oddArray[p] << endl;
}
}
int oddIndex = 0;
int evenIndex = 0;
int oddArray[oddIndex];
int evenArray[evenIndex];
As you can see you are initializing oddArray and evenArray with 0 size.What you can do is declare both arrays of size arraySize,or better you can use vectors
You use wrong initialization of arrays length
int oddArray[oddIndex];
int evenArray[evenIndex];
In this lines you create two arrays of zero length. Further use to these arrays will lead to undefined behaviors.
If you need an array with dynamically changing length you should use std::vector.
I've been trying to write a short program allowing the user to add entries to a "database", listing the entries they have put in, and the ability to clear all the entries without ending the program. Here's what i've got
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
struct BIRTH
{int month; int year;};
struct ID
{string name; bool vip; float score;
struct BIRTH date;} ;
int main(int argc, char** argv) {
ID **ptrarr;
ptrarr = new ID * [10];
for (int r=0; r<10; r++)
{ptrarr[r] = new ID[1] ;}
int counter = 0;
while(counter<100){
cout << "Type add to create a new entry" << endl;
cout << "Type list to see all entries" << endl;
cout << "Type clear to delete all entries" << endl;
cout << "Type exit to terminate" << endl;
string command = "0";
getline (cin,command);
if(command=="add")
{
cout << "Enter name" << endl;
getline (cin,ptrarr[counter][1].name);
cout << "VIP? 1 for yes, 0 for no" << endl;
cin >> ptrarr[counter][1].vip;
cout << "Enter score" << endl;
cin >> ptrarr[counter][1].score;
cout << "Month of birth" << endl;
cin >> ptrarr[counter][1].date.month;
cout << "Year of birth" << endl;
cin >> ptrarr[counter][1].date.year;
counter++;
}
else if(command=="list")
{
for (int i=0; i<counter; i++)
{int n=i+1;
cout << n << " "
<< ptrarr[i][1].name << " ";
if (ptrarr[i][1].vip)
{cout << "VIP ";}
cout << "Score: " << ptrarr[i][1].score << " "
<< "Born: " << ptrarr[i][1].date.month << "/" << ptrarr[i][1].date.year << endl;
}
}
else if(command=="clear")
{delete[] ptrarr;
cout << "Entries cleared" << endl;}
else if(command=="exit")
{return 0;}
else
cout << "try again" << endl;
}
return 0;
}
Now here's the deal: the following code successfully compiles, but when I type in the "add" command, the program crashes (achievement unlocked, didn't think it's possible to obtain with such a short code). The most important thing is that the array is made of a multitype structure and that the "clear" command wipes out all the entries in the array.
NOTE: I understand that there are thousand better ways to write this piece of code, but I'm writing it to practice the things I have covered so far regarding C++. So unless it is absolutely necessary for the code to run, please do not introduce any new gimmicks =)
Replace all ptrarr[counter][1] with ptrarr[counter][0] fixes the problem.
Further advices:
I. This code has redundancy:
ID **ptrarr;
ptrarr = new ID * [10];
for (int r=0; r<10; r++)
{ptrarr[r] = new ID[1] ;}
Replace it with:
ID *ptrarr;
ptrarr = new ID [10];
Then you do not need extra [0] at the end of each ptrarr[counter]
II. functions make your code more readable:
if(command=="add")
add();
else if(command=="list")
list();
else if(command=="clear")
clear();
else if(command=="exit")
return 0;
else
cout << "try again" << endl;
Then decisions are made in a smaller area (Good practice for large programs.)
III. There is another mistake in your code:
else if(command=="clear")
{delete[] ptrarr;
cout << "Entries cleared" << endl;}
Here you should reset the counter. Also if you regard my point (I) this part is fine. Otherwise, if you use new with a for loop, I am afraid that you need to delete with a for loop too. Merely removing the root of the array tree brings you memory leak!
Also, if you cleared the list by delete, wont you need to store data in the list anymore? Using delete in linked lists is a good idea, but it does not apply here. Just reseting the counter does the job and it does not show IDs in the list anymore. The for inside the list does only count up to the counter.
If you exit the program don't you free the memory?
I say
delete [] ptrarr;
is good for being at exit.
You are creating an an array of pointers, each one of which points to one element:
ptrarr[r] = new ID[1] ;
The maximum index that you can use with ptrarr[r] is 0. Since you are using ptrarr[counter][1], you are accessing memory that is out of bounds. This leads to undefined behavior. Crashing is one such undefined behavior.
There are other issues with your code that you may want to fix.
More out of bounds memory access
You are using:
int counter = 0;
while(counter<100){
...
getline (cin,ptrarr[counter][1].name);
That is again going to lead to undefined behavior if counter > 10 since you allocated only 10 pointers for ptrarr.
Deleting the contents
You are using:
else if(command=="clear")
{
delete[] ptrarr;
cout << "Entries cleared" << endl;
}
There are couple of problems with this:
You have memory leak. You never call delete [] on what ptrarr[0] - ptrarr[9] point to. You'll have to use:
else if(command=="clear")
{
for ( int i = 0; i < 10; ++i )
{
delete [] ptrarr[i];
}
delete[] ptrarr;
cout << "Entries cleared" << endl;
}
Remember that every allocation must have a corresponding deallocation. Otherwise, you are leaking memory.
Once you call delete [] ptrarr;, it points to dangling memory. I don't see any code that reallocates memory for ptrarr while you continue to use it.
You need to reallocate memory and reset counter to 0 when the user chooses "clear".
My suggestion
You don't two levels of pointers. You just need something like:
int const MAX_ITEMS = 100;
ID* IDarr = new ID[MAX_ITEMS];
Instead of ptrarr[counter][1], use IDarr[counter].
Use MAX_ITEMS in the expression of the while statement instead of the magic number 100.
int counter = 0;
while(counter<MAX_ITEMS){
When processing "clear", you don't need to deallocate or allocate memory. Just reset counter.
else if(command=="clear")
{
counter = 0;
cout << "Entries cleared" << endl;
}
Make sure to deallocate memory before returning from main.
Here's the complete main function with the changes:
int main(int argc, char** argv) {
const int MAX_ITEMS = 100;
ID* IDarr = new ID[MAX_ITEMS];
int counter = 0;
while(counter < MAX_ITEMS){
cout << "Type add to create a new entry" << endl;
cout << "Type list to see all entries" << endl;
cout << "Type clear to delete all entries" << endl;
cout << "Type exit to terminate" << endl;
string command = "0";
getline (cin,command);
if(command=="add")
{
cout << "Enter name" << endl;
getline (cin, IDarr[counter].name);
cout << "VIP? 1 for yes, 0 for no" << endl;
cin >> IDarr[counter].vip;
cout << "Enter score" << endl;
cin >> IDarr[counter].score;
cout << "Month of birth" << endl;
cin >> IDarr[counter].date.month;
cout << "Year of birth" << endl;
cin >> IDarr[counter].date.year;
counter++;
}
else if(command=="list")
{
for (int i=0; i<counter; i++)
{
int n=i+1;
cout << n << " " << IDarr[i].name << " ";
if (IDarr[i].vip)
{
cout << "VIP ";
}
cout
<< "Score: " << IDarr[i].score << " "
<< "Born: " << IDarr[i].date.month << "/" << IDarr[i].date.year << endl;
}
}
else if(command=="clear")
{
counter = 0;
cout << "Entries cleared" << endl;
}
else if(command=="exit")
{
// Don't use return 0;
// Just break out of the while loop so that memory
// can be deallocated at the end of this function.
break;
}
else
cout << "try again" << endl;
}
delete [] IDarr;
return 0;
}
Array indices start at 0.
ptrarr[counter][1] refers to the second element of ptrarr[counter]. ptrarr[counter] points to an array of one element.
try this :
if(command=="add") {
cout << "Enter name" << endl;
getline (cin,ptrarr[counter][0].name);
cout << "VIP? 1 for yes, 0 for no" << endl;
cin >> ptrarr[counter][0].vip;
cout << "Enter score" << endl;
cin >> ptrarr[counter][0].score;
cout << "Month of birth" << endl;
cin >> ptrarr[counter][0].date.month;
cout << "Year of birth" << endl;
cin >> ptrarr[counter][0].date.year;
counter++;
}
else if(command=="list") {
for (int i=0; i<counter; i++){
int n=i+1;
cout << n << " "<< ptrarr[i][0].name << " ";
if (ptrarr[i][0].vip){
cout << "VIP ";
}
cout << "Score: " << ptrarr[i][0].score << " "
<< "Born: " << ptrarr[i][0].date.month << "/" << ptrarr[i][0].date.year << endl;
}
}
Conclusion :
Just as you initialized counter with 0 you should have used 0 index to access the first element;
Same goes while listing.
Arrays are 0 index based.
I'm seriously confused right now. I'm working on a school project that uses overloading. I have a constructor that has two parameters, a lower index and upper index for an int array. Here is the constructor:
IntArray::IntArray(int lower, int upper){
arrLower = lower;
arrUpper = upper;
// Creates array size
size = arrUpper - arrLower;
operator[](size);
}
and when my program gets to this testing point via this function:
void test2() {
cout << "2. Array declared with two integers: IntArray b(-3, 6);" << endl << endl;
csis << "2. Array declared with two integers: IntArray b(-3, 6);" << endl << endl;
IntArray b(-3, 6);
//cout << b.low() << " " << b.high();
for(int i = b.low(); i <= b.high(); i++)
b[i] = i * 10;
b.setName("b");
cout << b << endl;
csis << b << endl;
wait();
}
it seizes and utilizes all of my cpu power. the low() and high() functions simply return arrLower and arrUpper. What I don't understand is why it works if I add
cout << b.low() << " " << b.high() << endl;
after the constructor call.
Why does adding a cout statement fix my problem? Am I not managing memory properly?
heres the full WIP program if you want to look at it. It's not done by a long shot.
https://gist.github.com/anonymous/963fb80351ae23c58f18